身份认证方案
2018-08-16 15:40:59 0 举报
AI智能生成
cookie session token jwt 的对比分析,包括产生背景,适用场景,工作原理,优缺点等
作者其他创作
大纲/内容
token
基本概念
Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌
产生背景
客户端请求频繁的情况下,服务端频繁的查询数据库进行用户名密码的对比产生大量的性能消耗
适用场景
需要进行用户身份认证的大部分场景
设备支持
web
移动设备
工作原理
1. 用户通过手机号和验证码发送请求<br>
2. 服务端验证通过,生成token,返回给客户端<br>
3.客户端保存token到本地,一般不保存在cookie里面
4.客户端每次请求带上token,一般放在请求头里面
5.服务端验证token,验证通过才执行请求
存储位置
客户端保存用户状态
服务端
不保存,采用密钥验证通过算法有效性
<b>保存到数据库,通过查询数据库进行对比验证</b><br>
保存到redis,通过查询redis对比验证
以上方案均支持分布式
特点
效率
服务端不保存token效率高
<b>服务端保存token到数据库效率低</b>
服务端保存token到redis效率较高
支持跨域访问
用户认证信息token通过HTTP头传输
服务端设置Access-Control-Allow-Origin:*使其能接受所有域的请求
安全
因为不依赖于cookie,避免CSRF攻击
cookie
基本概念
在 HTTP 协议下,服务端维护客户端状态的一种方式
产生背景
http协议无状态
客户端多次会话保持登录状态
存储少量信息到域名路径下
适用场景
记住我:用于自动登录
广告联盟用于精准推送
用户登录搜索引擎,搜索关键字A
搜索引擎后台保存用户搜索记录
网站M加入了搜索引擎建立的广告联盟
用户打开网站M,
设备支持
web浏览器:用户可禁用cookie
移动设备:不方便
用户可禁用cookie
有的手机默认禁用cookie
部分手机浏览器不支持cookie
属性
name
一个cookie的名称
value
一个cookie的值
domain
<b>为可以访问此cookie的域名</b>
path
访问domain下的path以及path的子路径时才会带上cookie
size
此cookie的大小,包括name+value的字节数
http
cookie的httponly属性。若此属性为true,则只有在http请求头中会带有此cookie的信息,而不能通过document.cookie来访问此cookie。
secure
设置是否只能通过https来传递此条cookie
expires/Max-Age
字段为此cookie超时时间。若设置其值为一个时间,那么当到达此时间后,此cookie失效。不设置的话默认值是Session,意思是cookie会和session一起失效。当浏览器关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie失效。
工作原理
客户端请求服务端
服务端返回set-cookie信息
客户每次请求带上cookie信息
存储位置
客户端
chrome
C:\Users\{UserName}\AppData\Local\Google\Chrome\User Data\Default
浏览器运行时:RAM
浏览器运行,退出网站:硬盘
浏览器退出:删除
优点
保持web浏览状态
服务端压力轻
缺点
存储尺寸有限
Firefox,Safari:4097byte
Opera:4096byte
Internet Explorer:4095byte
安全性低
http请求中,cookie是明文传输
cookie存在客户端,容易被窃取
浏览器有每个域名下cookie数量上限
Firefox:50
InternetExplorer8:50
Opera:30
不同浏览器同一域名下多个cookie选择策略不同
不方便跨域访问
nginx反向代理
jsonp
nodejs superagent
CSRF(跨站请求伪造)
利用浏览器访问域名时自动带上该域名下的cookie实现
用户S登录A网站并且没有退出,再进入到危险网站B,点击B的链接,这个链接是访问A网站的,但是用户S不知道这个链接干嘛的,可能只是一张图片,然后这个链接会自动带上A网站的cookie以用户S的身份去执行操作,例如银行转账等。
即使用户关闭浏览器也不一定有效,因为浏览器关闭之后,cookie如果还在有效期内,会保存到硬盘,当用户重新打开浏览器的时候,该cookie仍然有效,如果用户访问了危险网站,仍然可能受到攻击。
如何避免
检查referer字段
不同网站发起的请求referer值不同
实现简单,只需要增加一个过滤器或者拦截器接口
仍然存在风险,referer是有浏览器设置的,无法保证浏览器的实现,有的浏览器可篡改该值
在请求地址中添加 token 并验证
在 HTTP 头中自定义属性并验证
session
基本概念
在 HTTP 协议下,服务端维护客户端状态的一种方式
产生背景
解决cookie的安全性问题
适用场景
保持登录状态
购物车场景等
设备支持
web
移动设备
session通常采用cookie保存sessionId,所以移动设备对session的支持度和对cookie差不多
工作原理
客户端登录
服务端生成session,返回sessionId,sessionId设置在cookie里面
客户端每次请求带上cookie的sessionId
服务端根据sessionId找到session
禁用cookie的情况采用url重写的方式实现
存储位置
服务端:存储session的全部信息
内存
数据库
支持分布式
redis
支持分布式
客户端:存储session的唯一标示sessionId
优点
安全性相对较高
服务端维护用户状态
客户端只保存sessionId
缺点
服务端存储压力大
因为依赖cookie,所以同样存在csrf风险
jwt
基本概念
为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准
产生背景
子主题
适用场景
一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上
设备支持
web
移动设备
工作原理
<ol><li>用户通过手机号和验证码发送请求<br></li></ol>
2. 服务端验证通过,生成token,返回给客户端<br>
3.客户端保存token到本地,一般不保存在cookie里面
4.客户端每次请求带上token,一般放在请求头里面
5.服务端验证token,验证通过才执行请求
存储位置
客户端
服务端
存储数据加密解密用的secret
优点
无状态,扩展性强
构成简单,占用字节小,便于网络传输
因为json的通用性,跨语言支持
服务端不保存,减轻存储压力
缺点
续签困难:字符串生成参数里面包含过期时间,如果过期时间不一样那么字符串肯定不一样,可通过客户端主动刷新token解决
注销困难:服务端无状态,不保存token,所以无法保证用户退出登录之后,他使用的token已经失效。可以通过引入redis,用户主动退出时,将其token保存在redis,然后服务端验证token之前先去redis查询改token,如果存在说明过期。
具体实现
组成部分
头部
{
<br> "typ": "JWT",
<br> "alg": "HS256"
<br>}
typ 表示类型,固定为JWT
alg 表示算法
默认值HS256
HMAC with SHA-256
HS384
HMAC with SHA-384
HS512
HMAC with SHA-512
RS256
RSASSA-PKCS1-v1_5 with SHA-256
RS384
RSASSA-PKCS1-v1_5 with SHA-384
RS512
RSASSA-PKCS1-v1_5 with SHA-512
ES256
ECDSA with curve P-256 and SHA-256
ES384
ECDSA with curve P-384 and SHA-384
ES512
ECDSA with curve P-521 and SHA-512
对头部进行BASE64编码得到字符串
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
载荷
{
<br> "sub": "appuser",
<br> "iat": 1516239022,
<br> "iss":"qinc",
<br> "exp":1516539022,
<br> "aud":"superapp",
<br> "name": "John Doe",
<br> "userId":"asdasdasdasd",
<br> "passportId":"12412421423"
<br>}
sub 该JWT所面向的用户
iss 该JWT的签发者
aud 接收该JWT的一方
exp 什么时候过期,这里是一个Unix时间戳
iat 在什么时候签发的
name ,userId ,passportId 属于自定义属性,可任意添加
对载荷进行base64编码得到字符串
eyJzdWIiOiJhcHB1c2VyIiwiaWF0IjoxNTE2MjM5MDIyLCJpc3MiOiJxaW5jIiwiZXhwIjoxNTE2NTM5MDIyLCJhdWQiOiJzdXBlcmFwcCIsIm5hbWUiOiJKb2huIERvZSIsInVzZXJJZCI6ImFzZGFzZGFzZGFzZCIsInBhc3Nwb3J0SWQiOiIxMjQxMjQyMTQyMyJ9
因为base64可以解码,所以不建议设置用户的敏感信息,比如身份证电话号码银行卡等
签名
HMACSHA256(<br> base64UrlEncode(header) + "." +<br> base64UrlEncode(payload),<br><b><i>your-256-bit-secret</i></b><br>)
签名由头部的base64编码字符串加载荷的base64编码字符串加密钥用英文句号隔开拼接而成的字符串通过HMACSHA256加密得到
此处的密钥secret也可以先进行一次base64编码
最后得到加密出来的签名
SfEzJ5n47vNRcmgdV3EreK1fWLwfC2pfJoiIToa-m9M
示例
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhcHB1c2VyIiwiaWF0IjoxNTE2MjM5MDIyLCJpc3MiOiJxaW5jIiwiZXhwIjoxNTE2NTM5MDIyLCJhdWQiOiJzdXBlcmFwcCIsIm5hbWUiOiJKb2huIERvZSIsInVzZXJJZCI6ImFzZGFzZGFzZGFzZCIsInBhc3Nwb3J0SWQiOiIxMjQxMjQyMTQyMyJ9.SfEzJ5n47vNRcmgdV3EreK1fWLwfC2pfJoiIToa-m9M
验证原理
如果有人在不知道密钥secret的情况下将头部和载荷的数据解码之后进行修改,然后编码在重新进行签名
服务端收到token之后,对头部和载荷再次做签名处理,将得到的结果和传入的签名进行比较,因为伪造的token生成签名的密钥secret和服务器的密钥不一致,所以对比的结果肯定是不一致的。服务器即可判定token不合法。
token合法的情况下,再将token的载荷里面的过期时间与当前时间比较,验证有效性。
验证通过放行,不通过返回相应的提示
java推荐接入方案
https://github.com/auth0/java-jwt
在哪里进行token验证
网关
减少远程调用,提高性能
用户服务
权限认证服务
0 条评论
下一页