授权与认证实战

登录方式的变迁

在传统的 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 进行令牌续约。

使用 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 授权,格式如下所示。

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

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

MAC Token 使用

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

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等信息。

再来回顾下 MAC Token 的格式。

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

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

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

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20171211G0243100?refer=cp_1026

扫码关注云+社区