# OAuth认证
- OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。
- 每个令牌授权对应一个特定的网站(如视频网站)在特定时间内(如2小时内)访问特定的资源。
- 这样OAuth让用户可以授权第三方网站访问她, 存储在另外服务提供者的某些特定信息,而非所有内容。
例:微信网页授权就是授权码模式的OAuth授权模式:
1.用户登录某个视频网站
2.视频网站提供一个微信授权页面
3.用户同意授权,视频网站服务器重定向到之前设置好的redirect_url(服务器地址),并附带上授权码(code)
4.视频网站服务器用上一步获取到的code去向微信授权服务器发送请求,获取access_token,即令牌
5.视频网站服务器拿到access_token后去请求微信授权服务器获取用户基本信息,如头像、昵称等
# Cookie-Session认证
- 用户输入用户名、密码或用短信验证码方式登录系统
- 服务器验证后,创建一个session信息,并且生成sessionId存到cookie,发送回浏览器
- 下次客户端再请求,自动带上cookie信息,服务器通过cookie获取sessionId进行session信息校验
缺点:
1.只能用于web,不能用于app
2.使用cookie需要考虑跨域问题
3.cookie存在CSRF(跨站请求伪造)风险
4.session存在服务器,需要考虑服务器的负担以及同步问题
CSRF(跨站请求伪造):盗用cookie信息,以你的名义发送恶意请求
- 验证HTTP Referer字段,它记录了http请求的来源地址
- 请求地址中添加token验证
- 在http头中自定义属性并验证
# 基于JWT的Token认证
- 用户输入密码或者短信验证登录系统
- 服务端验证,将认证信息通过指定算法进行加密,将加密结果发送给客户端,加密的字符串即是JWT
- 客户端拿到token存储到本地LocalStorage或本地数据库
- 下次客户端再请求,将token附加在http请求的header中
- 服务器获取到header中的token,通过相同算法对token中的用户名以及其他信息进行加密验证,如果验证结果相同, 则说明这个请求是正常的,未经过篡改
优点:
1.使用json作为数据传输,有广泛的通用性,并且体积小,便于传输
2.不需要服务端保存任何信息
3.JWT可以存储业务相关信息,如:用户名、角色等等
JWT组成: header.payload.signature
- header
{
"alg": "HS256", // 该字段指定生成signature的算法,默认值为 HS256
"typ": "jwt" // 默认值为 jwt
}
生成的base64UrlEncode编码为: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
- payload
{
"iss": "admin", //该JWT的签发者
"iat": 1535967430, //签发时间
"exp": 1535974630, //过期时间
"nbf": 1535967430, //该时间之前不接收处理该Token
"sub": "www.admin.com", //面向的用户
"jti": "9f10e796726e332cec401c569969e13e" //该Token唯一标识
}
生成的base64UrlEncode编码为: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
- signature
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
123456
)
这个操作是对header和payload机械能baseUrlEncode编码后进行拼接,通过key(这里是123456)进行HS256算法签名
得到的签名的base64UrlEncode编码为: keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU
也被称为签名哈希:HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
key是什么
key是只保存与服务端的secret,不可被用户知晓
以上三个部分用'.'来拼接起来得到的字符串,就是整个JWT
← 一次完整的HTTP请求与响应 单点登录 →