常见的鉴权方式有两种,一种是基于session,另外一种是基于token方式的鉴权,咱们来浅谈一下两种 鉴权方式的区别。java
业界经常使用的受权标准有两种,一种是使用auth2,这种方式更适合于相似第三方受权登陆,好比微信、微博、QQ信任登陆业务。另外一种是oauth,即第三方无需知道用户和密码就能够申请得到该资源的受权,更适用于对用户的权限校验并分配访问权限,好比常见的登陆后分配可见资源(按钮、菜单等)类型网站。redis
Javashop电商系统 采用的是oauth方式的鉴权标准。咱们以系统的应用为例来介绍oauth的方案。spring
1. 登陆
服务端校验密码,成功后返回access_token和refresh_token,客户端记录上述token。
2. 访问API
在访问API以前解析access_token,而且查看是否过时,若是不过 期则请求API,若是过时,则要刷新令牌,在请求API。
3. 刷新token
携带有效期的refresh_token换回有效token,若是refresh_token过时,则须要用户从新登陆。
4. 注销
请求注销api,服务器端和客户端应同时删除token的存储。api
1. 客户端请求API
携带access_token信息,若是生成环境不会直接携带access_token,会使用加密后的签名校验。祥见如下防重放机制。
2. 获取token
根据环境不一样而有不一样的获取token方式。
3. 解析token
经过JWT工具将token解析。
4. 由redis读取token
根据uid拼接key读取access_token, 若是不存在这个用户的token说明已经登出。
5. 验证token
判断次token是否属于此uid,判断token是否过时,若是过时则进行如下刷新token的流程。
6. 注入权限
若是token验证成功,根据user信息生成权限注入到spring安全上下文中。浏览器
刷新token流程安全
1. 客户端请求API
携带refresh_token,若是是生产环境不会直接携带refresh_token信息,详见如下防重放攻击。
2. 获取token
根据环境不一样而有不一样的获取token方式。
3. 解析token
经过JWT工具将token解析。
4. token读取
根据uid拼接key读取出access_token,若是不存在这个用户的token说明用户已经登出。
5. 验证token
判断此token是否属于此uid,判断token是否已通过期,若是过时,则返回refresh_token过时错误,此时用户须要从新登陆。
6. 刷新token
若是refresh_token 验证成功,则从新生成access_token和refresh_token,上述有效期以当前时间向后计算,替换此用户在redis中的token,并将token返回给客户端。服务器
1、 参数的读取
1. 在生产环境时,不能直接传递token,而是要传递签名数据,服务器端验签后由Redis中获取签名。
2. 若是是非生产环境,直接由header中读取token。
2、 生产环境传递以下参数
memberid (用户id)
nonce(随机字串,6位)
timestamp(当前时间戳,到秒)
sign= md5( uid+ nonce + timestamp +token )
3、 验证逻辑
1. 验证时间戳
判断时间戳是否起过60s,大于60s则判别为重放攻击。微信
2. 验证nonce
首先验证nonce在 reids中是否存在,若是存在,则判别为重放攻击,不然将nonce记录在redis中(key为:"nonce"+uid+"_"+nonce),失效时间为60s。
3. 验证sign
md5( uid+ nonce + timestamp +token ) 验证是签名是否经过。
4. 验证token
经过uid拿到token ,验证逻辑同验权流程。cookie
固然在不一样的业务场景下实现方案是多种多样的,仅以此方案抛砖引玉,供你们参考。 session
易族智汇(javashop)原创文章