几种常见的认证机制

1), Http Basic Auth

  • Http Basic Auth 简单点说明就是每次请求API时都提供用户的 username 和 password ,简而言之,Basic Auth 是配合 RESTful API 使用的最简单的认证机制,只需提供用户名密码即可,但由于有把用户名密码暴露给第三方客户端的风险,在生产环境下被使用的越来越少。
  • 因此,在开发对外的RESTful API 时,尽量避免采用HTTP Basic Auth 。

2),Cookie Auth

  • Cookie 认证机制就是为一次请求认证在服务端创建一个 Session 对象,同时在客户端的浏览器创建了一个 Cookie 对象。
  • 通过客户端带上来 Cookie 对象来与服务器端的 Session 对象匹配来实现状态管理的。
  • 默认的,当我们关闭浏览器的时候,Cookie 会被删除。 但是可以通过修改 Cookie 的 expire 使 cookie 在一定时间内有效。

                                           

3), OAuth -第三方认证登录

  • OAuth (开放授权) 是一个开放的授权标准,允许用户让第三方应用访问改用户在某一 web 服务上存储的私密的资源(如,照片,视屏,联系人列表等),而无需将用户名和密码提供给第三方应用。
  • OAuth 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的第三方系统(如,视屏编辑网站)在特定的时段(如,接下来2个小时内)访问特定的资源(如,仅仅是某一相册中的视频)。这样,OAuth 让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容

                                       

  1. 这种基于 OAuth 的认证机制适用于个人消费者类的互联网产品,如社交类APP等应用,但是不太适合自由认证权限管理的企业应用。

4),Token Auth

  • 使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概流程是:
  1. 客户端使用用户名和密码请求登录
  2. 服务端收到登录请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token ,再把这个Token 发送给客户端
  4. 客户端收到 Token 以后把它存储起来,比如说放在 Cookie 里
  5. 客户端每次向服务端请求资源的时候带着服务端签发的Token 
  6. 服务端收到请求后,然后验证客户端请求里面带着的Token,如果验证成功,就向客户端返回请求的数据

                                       

Token Auth 的有点

     Token机制相对于Cookie机制又有什么好处呢?

  • 支持跨域访问 : Cookie 是不允许跨域访问的,这一点对 Token 机制是不存在的,前提是传输的用户认证信息是通过HTTP头传输
  • 无状态(也称为:服务端可扩展行) : Token 机制在服务端不需要存储session 信息,因为Token 自身包含了所有登录用户的信息,只需要在客户端cookie或本地介质存储状态信息。
  • 更适合CDN : 可以通过内容分发网络请求你服务端的所有资料(如 javascript,HTML,图片等)而你的服务端只需要提供API即可。
  • 去耦 : 不需要绑定到一个特定的身份验证方案。Token 可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成即可。
  • 更适合于移动应用 : 当你客户端是一个原生平台(IOS , Android ,Windows 等)时,Cookie 是不被支持的(你需要通过Cookie容器进行处理),这时采用Token 认证机制就会简单的多。
  • CSRF : 因为不在依赖与Cookie ,所以你就不需要开率对 CSRF(跨站请求伪造)的防范。
  • 性能 : 一次网络往返时间(通过数据库查询session信息)总比做一次 HMACSHA256 计算的 Token 验证和解析要费时得多。
  • 不需要为登录页面做特殊处理 : 如果你使用Protractor 做功能测试的时候,不需要为登录页面做特殊处理。
  • 基于标准化 : 你的API 可以采用标准化的 JSON Web Token (JWT) 这个标准已经存在多个后端库(.NET , Ruby , Java ,PHP)和多家公司的支持(如Firebase ,google , microsoft)

5),基于JWT 的Token 认证机制实现

5-1), 什么是JWT

  • Json Web Token (JWT) 是一个非常轻巧的规范。 这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息。

5-2),JWT 组成

  1. 一个 JWT 实际上就是一个字符串 ,它由三部分组成 , 头部 , 载荷签名

5-2-1),头部 (Header)

  • 头部用于描述关于该 JWT 的最基本的信息,例如 其类型以及签名所用的算法等。 这也可以被表示成一个 JSON 对象。
{"typ":"JWT","alg":"HS256"}
JTdCJTIydHlwJTIyJTNBJTIySldUJTIyJTJDJTIyYWxnJTIyJTNBJTIySFMyNTYlMjIlN0Q=

注意

  • Base64 是一种基于 64 个可打印字符串来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即 3个字节需要用4个可打印字符来表示。 JDK 中提供了非常方便的 BASE64Encoder 和 BASE64Decoder ,用它们可以非常方便的完成基于Base64的编码和解码。

5-2-2),载荷 (plyload)

  • 载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分:

(1),标准中注册声明(建议但不强制使用)

iss: jwt签发者 
sub: jwt所面向的用户 
aud: 接收jwt的一方 
exp: jwt的过期时间,这个过期时间必须要大于签发时间 
nbf: 定义在什么时间之前,该jwt都是不可用的. 
iat: jwt的签发时间 
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

(2),公共的声明

  • 公共的声明可以添加任何的信息,一般添加用户的相关信息或业务需要的必要信息,但不建议添加敏感信息,因为该部分在客户端可解密。

(3)私有的声明

  • 私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为 base64 是对称解密的,意味着该部分信息可以归类为明文信息。
  • 这个指的就是自定义的 claim 比如前面那个结构举例中的 admin 和 name 都属于自定义的 claim 。这些 claim 跟JWT 标准规定的 claim 区别在于 : JWT 规定的 claim ,JWT 的接收方在拿到JWT之后,都知道怎么对这些标准 claim 进行验证(还不知道是否能够验证),而parivate claims不会去验证,除非明确告诉接收方要对这些 claim 进行验证以及规则才行。

定义一个 载荷(payload)

{"sub":"1234567890","name":"John Doe","admin":true}
然后将其进行 base64 编码,得到 Jwt 的第二部分。
 
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

5-2-3),签证 signature

  • JWT 的第三部分是一个签证信息,这个签证信息由三部分组成 header(base64后) , payload(base64后) 和 secret(盐值)

这个部分需要base64 加密后的header 和 base64 加密后的payload使用,连接组成字符串,然后通过 header 中声明的加密方式进行加盐secret组成加密,然后就构成了 jwt 的第三部分。

TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

将这三部分用.连接成一个完成的字符串,构成了最终的jwt

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6I kpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7Hg Q

注意

  • secret 是保存在服务端的,jwt 的签发生成也是在服务端的, secret 就是用来进行jwt 的签发 和 jwt 的验证 ,所以它就是你服务器的私钥,任何场景都不应该流露出去,一旦客户端得知这个secret ,那就意味着客户端可以自我签发 JWT了。
发布了256 篇原创文章 · 获赞 188 · 访问量 65万+

猜你喜欢

转载自blog.csdn.net/qq_40646143/article/details/103361823
今日推荐