acess token
-
访问资源接口(api)时所需要的资源凭证
-
简单token 的组成: uid(用户唯一的身份标识) 、time (当前时间的时间戳) ,sign(签名,token的前几位以hash算法压缩成的一定长度的16进制字符串)
-
特点:
-
服务端无状态变化、可扩展性好
-
支持移动端设备
-
安全
-
支持跨域程序调用
-
token 的身份验证流程
- 客户端使用用户名和密码进行登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个token 并把这个token 发送给客户端
- 客户端收到token后,会把它存储起来,比如放在cookie 里 或者 localstorage里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的token
- 服务端收到请求后,先验证客户端请求里带着的token ,如果验证成功,就向客户端返回请求的数据
- 优点:
- 每一次请求都需要携带token ,需要把token 放到http的header 里
- 基于token 的用户验证是一种服务端无状态的认证方式,服务端不用存放token数据,用解析token的计算时间换取 session的存储空间,从而减轻服务器的压力,减少频繁的查询数据库
- token 完全由应用管理,所以它可以避开同源策略
- token生成示例
使用用户唯一id 系统时间 随机数 过期时间得到用户信息数据,对用户信息数据进行rsa非对称加密/aes对称加密得到一个加密字符串a,将加密字符串a再次进行签名等到一个签名数据。然后将签名数据和加密字符串进行拼接,最后使用base64进行编码,得到最终的token令牌。
/** * * @param tokenbody 实例对象,通常为bean * @param minute 过期时间 单位:min * @param
* @return */ public static string createtoken(t tokenbody, int minute) { long now = system.currenttimemillis() / 1000; gson gson = new gson(); jsonobject jsonbody = new jsonobject(); jsonbody.addproperty("body", gson.tojson(tokenbody)); string randomalphabetic = randomstringutils.randomalphabetic(3); jsonobject jsonheader = new jsonobject(); jsonheader.addproperty("now", now); jsonheader.addproperty("rand_num", randomalphabetic); jsonheader.addproperty("expire", (now minute * 60)); string token = null; try { byte[] encryptcontent = generateencryptbody(jsonheader.tostring(), jsonheader.tostring()); byte[] signwithencrypt = generatesignwithencrypt(encryptcontent); token = joiner.on(".").join(new string[]{ base64encoder( jsonheader.tostring().getbytes("utf-8")), base64encoder(encryptcontent), base64encoder(signwithencrypt)} ); } catch (exception e) { e.printstacktrace(); } return token; }
常见的鉴权模式
- session-cookie
- token验证(jwt sso单点登录)
- oauth2.0 (开放授权)
jwt 与 token 的区别
- 相同:
- 都是访问资源的令牌
- 都可以记录用户的信息
- 都是使服务端无状态变化
- 都是验证成功后,客户端才能访问服务端上受保护的资源
-
-
区别
- token: 服务端验证客户端发送过来的token 时,还需要查询数据库获取用户信息,然后验证token 是否有效
- jwt: 将token 和 payload 加密后存储于客户端,服务端只需要使用秘钥进行校验即可,不需要查询或者减少查询数据库,因为jwt自包含了用户信息和加密的数据