登录方式的变迁

在传统的 MVC 模式中,一般使用 Cookie + Session 保持用户的登录状态。其中,当用户首次访问服务器的时候,服务器为每个用户单独创建一个 Session 对象,并分配一个新的 SessionID,此时 SessionID 通过 Cookie 保存在客户端。当用户再次访问服务器的时候,携带保存 SessionID 的 Cookie 给服务器,服务器查询是否存在这个 SessionID,如果存在,即认为用户处于登录状态,如果没有对应的 SessionID,服务器会给分配一个新的 SessionID。

当前后端分离后,服务端的 API 设计一般是无状态的,因此不能使用 Cookie + Session 保持用户的登录状态。此时,就需要使用 Token 令牌。服务端接收到前端发送的用户名和密码后,验证用户名和密码是否正确。如果用户名和密码不正确,则返回错误信息。如果用户名和密码正确,则生成一个随机且不重复的 Token 令牌,这个 Token 令牌是用户身份的唯一标识。一般情况下,前端将 Token 令牌保存到 Cookie 中,并设置 HttpOnly 属性。当用户退出系统时,前端调用服务端的“用户注销”接口,销毁 Token 令牌。

Oauth2 协议的授权与认证原理

图片

OAuth 是一个关于授权的开放网络标准,目前的最新版本是 OAuth 2.0,不兼容 OAuth 1.0。OAuth 2.0 允许第三方网站在用户授权的前提下访问用户在服务商那里存储的各种信息。这种授权无需将用户提供用户名与密码提供给该第三方网站。实际上,OAuth 2.0 允许用户提供一个令牌给第三方网站,一个令牌对应一个特定的第三方网站,同时该令牌只能在特定的时间内访问特定的资源,用户在客户端使用用户名和密码在用户中心获得授权,然后客户端在访问应用是附上 Token 令牌。此时,应用接收到客户端的 Token 令牌到用户中心进行认证。

OAuth2.0 认证流程中,最重要的两个步骤是获取 access token 与使用 access token 调用 API。获取 access token 的过程中,用户登录成功之后,客户端会向用户中心获取 access token,用户中心验证合法性并返回一个 access token,此时客户端需要存储 access token,以便在 access token 有效期内复用。

图片

实际上,获取 access token 的过程就是用户登录的过程。在服务端 RESTful API 接口的设计中,这个接口采用 POST 请求,在用户登录成功后,服务端会响应 accesstoken、expiresin、refreshtoken等信息。注意的是,在有效期内,accesstoken 可以一直使用,只有当 accesstoken 过期时,才需要再次调用接口获取 accesstoken。如果想让 accesstoken 长期有效,可以通过 refreshtoken 进行令牌续约。

客户端请求内容URL:[POST]{{project_url}}/oauth/tokenHeader:Accept : application/jsonContent-Type : application/jsonBody:{  "username" : "lgz",   "password" : "68f43abb5739c215fdfa4ae872d155ac"}服务端响应内容{  "access_token": "32e2517b-f13e-4dca-bbd3-86ea6cca037a", // access_token  "token_type": "bearer",                                       // 认证方式  "refresh_token": "c24a5fb6-cfd3-41da-9795-5d21150361be",// 刷新 access_token  "expires_in": 10122                                            // 过期时间}

使用 access token 调用 API 的过程中,用户发起请求后,应用需要验证 access token,以及用户是否具有操作权限,满足条件才可以成功获取资源。注意的是,如果验证 access token失败,证明这个 access token 是不合法,例如用户名或密码错误,或者是伪造的 access token。还有一种情况是 access token 已经过期失效,这种情况下,服务端会返回 401 错误码,告知客户端“未授权”。 如果验证用户没有对资源的操作权限,服务端会返回 403 错误码,告知客户端“不允许访问”。

一般情况下,access token 会添加到 HTTP Header 的Authorization 参数中使用,其中经常使用到的是Bearer Token 与Mac Token。如果希望进一步了解 OAuth2.0 ,可以阅读 https://oauth.net/2/。

Bearer Token 使用

Bearer Token 适用于安全的网络下 API 授权,格式如下所示。

Bearer 32e2517b-f13e-4dca-bbd3-86ea6cca037a

在用户登录成功后,服务端会响应 accesstoken、expiresin、refreshtoken等信息。事实上,Bearer Token 所包含的信息就是 accesstoken。

客户端请求内容URL:[POST]{{project_url}}/oauth/tokenHeader:Accept : application/jsonContent-Type : application/jsonBody:{  "username" : "lgz",   "password" : "68f43abb5739c215fdfa4ae872d155ac"}服务端响应内容{  "access_token": "32e2517b-f13e-4dca-bbd3-86ea6cca037a", // access_token  "token_type": "bearer",                                 // 认证方式  "refresh_token": "c24a5fb6-cfd3-41da-9795-5d21150361be",// 刷新 access_token  "expires_in": 10122                                     // 过期时间}

使用 access token 调用 API 的过程中,需要进行 Bearer Token 认证,必须将Bearer Token 的信息放在 HTTP Header 中的 Authorization 里面。

curl "https://{{project_url}}/depts"     -H "Authorization: Bearer 32e2517b-f13e-4dca-bbd3-86ea6cca037a"

MAC Token 使用

MAC Token 适用于不安全的网络下 API 授权,格式如下所示。

Authorization: MAC id="h480djs93hd8",  ts="1495896438",  nonce="dj83hs9s",  mac="SLDJd4mg43cjQfElUs3Qub4L6xE="

MAC 是 message authentication code 的简称,指的是消息认证码,它是一种确认完整性并进行认证的技术,因此通过 MAC 可以验证消息是否被篡改。MAC 算法主要包括 MD 与 SHA 两大系列消息摘要算法。MD 算法有 HmacMD2、 HmacMD4、 HmacMD5 三种算法;SHA 算法有 HmacSHA1、 HmacSHA224、 HmacSHA256、 HmacSHA384、 HmacSHA512 五种算法。其中,HMAC 是通过哈希算法来实现消息认证码,因为它性能较好,被广泛使用。MAC Token 一般使用 HmacSHA512 算法用于完整性检查。

MAC Token 也可以用于客户端登录,当用户登录成功后,服务端会响应 accesstoken、expiresin、refreshtoken、mackey、mac_algorithm等信息。

客户端请求内容URL:[POST]{{project_url}}/oauth/tokenHeader:Accept : application/jsonContent-Type : application/jsonBody:{  "username" : "lgz",   "password" : "68f43abb5739c215fdfa4ae872d155ac"}服务端响应内容{  "access_token": "32e2517b-f13e-4dca-bbd3-86ea6cca037a", // access_token  "token_type": "mac",                                    // 认证方式  "refresh_token": "c24a5fb6-cfd3-41da-9795-5d21150361be",// 刷新 access_token  "expires_in": 10122,                                    // 过期时间"mac_key":"adijq39jdlaska9asud",                          // HHMAC 的密钥   "mac_algorithm":"hmac-sha-256"                          // MAC 的加密算法名称}

再来回顾下 MAC Token 的格式。

Authorization: MAC id="32e2517b-f13e-4dca-bbd3-86ea6cca037a ",  ts="1495896438",  nonce="dj83hs9s",  mac="SLDJd4mg43cjQfElUs3Qub4L6xE="

其中,id 是 accesstoken,ts 是请求登录成功后生成的服务器时间戳,nonce 是由客户端生成的随机码,而 mac 是由 HmacSHA512 算法计算消息内容获得。这里,requestcontent 的内容可以是客户端生成的随机码、请求的方法、请求的域名、请求的资源路径等信息构成的字符串。

mac = base64(hmac(mac_key, mac_algorithm, request_content))

服务端在调用 API 的过程中,对 HTTP Header 中的 Authorization 的 MAC Token 进行校验,包括判断 access_token 是否过期、判断 Mac 签名是否错误。其中,判断Mac 签名是否错误,主要将客户端请求的 mac 与服务端依据客户端生成的随机码、请求的方法、请求的域名、请求的资源路径等信息构成的字符串重新由 HmacSHA512 算法计算生成的字符串进行比对。

此外,MAC Token 具有时效性且只能使用一次,因此它是一次性的Token,可以防止重放***。MAC Token 的保管可以利用 Redis 存储,并设置过期时间,例如 5 分钟。当 Token 在有效时间内被使用后,需要从 Redis 销毁这个 Token。


更多相关文章

  1. 69.批量创建mysql用户
  2. 如何检测用户有关退出页面的信息?
  3. 如何在用户选择操作后获取当前日期和时间
  4. Symfony 2在用户站点上动态添加字段以形成
  5. Internet Explorer导致无效的真实性令牌错误
  6. Yii - 加载ajax表单元素的用户端验证
  7. EasyUI动态展示用户信息
  8. j2ee的web项目,有最终的html代码(即f12看到的最终给用户浏览器展示
  9. golang写服务端程序,作为文件上传与下载的服务器。配合HTML5以网

随机推荐

  1. PHP 多进程和多线程的优缺点
  2. PHP 排序算法之插入排序
  3. PHP如何执行耗时脚本实时输出内容
  4. PHP 排序算法之希尔排序
  5. PHP非阻塞批量推送数据
  6. PHP实现微信支付(jsapi支付)流程的方法
  7. 关于PHP中单例模式的实现
  8. PHP怎么实现微信申请退款
  9. PHP随机生成不重复的8位卡号(数字)和卡密(字
  10. php怎么获得昨天0点的时间戳