LLwanran / front_end_studying

前端知识要点
https://llwanran.github.io/front_end_studying/
2 stars 1 forks source link

API 认证授权技术发展史 #28

Open LLwanran opened 5 years ago

LLwanran commented 5 years ago

昨日偶然隐约听到梓铭和炳权在讨论token的问题,可能是小程序项目用到了吧,不禁让我饶有兴致地写点这方面的东西,和大家分享一下:

1. HTTP Basic时代

也就是传统的使用 username 和 password 来进行登录,后端将 username:password 形式进行Base64编码得到一个字符串,放到HTTP头 Authorization 字段中,形成 Authorization: Basic *****,然后发送到服务端,服务端根据认证的结果,成功就返回200,失败就是401 一般安全起见要配合TLS/SSL的安全加密方式来使用 但这种把用户名和密码同时放在公网上传输的方式有点不太好,因为Base64不是加密协议,而是编码协议,所以就算是有HTTPS作为安全保护,给人的感觉还是不放心

2. Digest Access时代

即HTTP 摘要认证 其基本思路是,请求方把用户名口令和域做一个MD5 – MD5(username:realm:password) 然后传给服务器,这样就不会在网上传用户名和口令了 但是,因为用户名和口令基本不会变,所以,这个MD5的字符串也是比较固定的,因此,这个认证过程在其中加入了:nonce和qop 其中的 nonce 为服务器端生成的随机数,qop 用作安全防护 然后,客户端做 HASH1=MD5(MD5(username:realm:password):nonce:cnonce) 其中的 cnonce 为客户端生成的随机数 这样就可以使得整个MD5的结果是不一样的,PHP那边我们熟称“加盐加密”,2011年国内发生了多起大型站点用户信息泄露事件,像CSDN、金山、天涯社区、当当网、YY语音等,当时它们主流都是采用的这种认证方式 这种比之前的方式要好一些,因为没有在网上传递用户的密码,而只是把密码的MD5传送过去,相对会比较安全,而且,其并不需要是否TLS/SSL的安全链接 但是如果 password 不够复杂,其实是可以被暴力破解的,而且,整个过程是非常容易受到中间人攻击

3. App Secret Key + HMAC

是一种用于给消息签名的技术,也就是说,我们怕消息在传递的过程中被人修改,所以,我们需要对消息进行一个MAC算法,得到一个摘要字串,然后,接收方得到消息后,进行同样的计算,然后比较这个MAC字符串,如果一致,则表明没有被修改过,一般和SHA-256算法来配合 整个过程非常复杂就不细说了,有兴趣请自行查阅相关资料,比如微信的签名算法

4. JWT – JSON Web Tokens(主流)

JWT是一个比较标准的认证解决方案,这个技术在Java圈里应该用的是非常普遍的 大概流程是: 1、用户使用用户名和口令到认证服务器上请求认证 2、认证服务器验证用户名和口令后,以服务器端生成JWT Token,这个token的生成过程如下: 认证服务器还会生成一个 Secret Key(密钥) 对JWT Header和 JWT Payload分别求Base64。在Payload可能包括了用户的抽象ID和过期时间 用密钥对JWT签名 HMAC-SHA256(SecertKey, Base64UrlEncode(JWT-Header)+'.'+Base64UrlEncode(JWT-Payload)); 3、然后把 base64(header).base64(payload).signature 作为 JWT token返回客户端 4、客户端使用JWT Token向应用服务器发送相关的请求。这个JWT Token就像一个临时用户权证一样 JWT除了支持HMAC-SHA256的算法外,还支持RSA的非对称加密的算法 应用场景:无状态的分布式API

OAuth 1.0忽略,现在很多平台基本都是遵循OAuth 2.0,但还是有开放OAuth 1.0平台的,比如:新浪微博、QQ1.0平台等

5.OAuth 2.0(主流)

以上几个API认证方式都是要向Client发一个密钥(或是用密码)然后用HASH或是RSA来签HTTP的请求,这其中有个主要的原因是,以前的HTTP是明文传输,在传输过程中很容易被篡改,于是才搞出来一套安全签名机制,所以,这些认证的玩法是可以在HTTP明文协议下玩的 这种使用签名方式可以看到是比较复杂的,对于开发者来说,也是很不友好的,开发过程中非常容易出错 OAuth 2.0依赖于TLS/SSL的链路加密技术(HTTPS),完全放弃了签名的方式,认证服务器再也不需要返回什么 token secret 的密钥了 国内微信、支付宝均是案例 应用场景:外包认证服务器 && 大型企业解决方案

注意:JWT是一个“认证规范”,OAuth是一个“开放标准网络协议”,并不是同一个类型的东西