
0x01 cookie/session
说到token就必然绕不开cookie和session。
cookie:由服务端给客户端颁发的一张通行证,用来验证客户端的身份,本质上是一段在浏览器上以KV形式存储的文本数据,包含了session相关信息。用于解决HTTP协议无状态的问题,所以cookie是一个会话跟踪机制,是有状态的。
session:当客户端请求服务端通过验证后,服务端会生成保存身份认证相关的session数据,并将session相关信息写入cookie返回给客户端,然后客户端将cookie保存到本地。之后两端就通过核对session信息来确认可信状态。session 可能会存储在内存、磁盘、数据库里,可能需要在服务端定期的去清理过期的 session。
0x02 token
既然有了cookie/session为啥还需要token呢
优点:
1、无状态、可扩展
2、安全性
3、可扩展性
4、多平台跨域/单点登陆
5、基于标准
6、缓解服务器内存压力/增大服务器计算压力
格式:
UID + TIME + SIGN [+ OTHER]
0x03 实施
JSON Web Tokens(JWT)
组成:
- header
用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等
1 | { |
base64一下
ewogICJ0eXAiOiAidG9rZW7nsbvlnosiLAogICJhbGciOiAi562+5ZCN566X5rOVIgp9
- payload
标准文档:https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1
可以在其中添加这些字段
1 | iss:Issuer,发行者 |
1 | Map<String , Object> payload=new HashMap<String, Object>(); |
上边代码中添加的字段如下
1 | { |
base64编码
ewogICAgImlhdCI6IOW9k+WJjeaXtumXtCwKICAgICJleHAiOiDov4fmnJ/ml7bpl7QsCiAgICAidWlkIjogIjAwNyIKfQ==
这样payload就生成好了
- signature
将header和payload生成的base64编码通过.
连接起来,如下
ewogICJ0eXAiOiAidG9rZW7nsbvlnosiLAogICJhbGciOiAi562+5ZCN566X5rOVIgp9.ewogICAgImlhdCI6IOW9k+WJjeaXtumXtCwKICAgICJleHAiOiDov4fmnJ/ml7bpl7QsCiAgICAidWlkIjogIjAwNyIKfQ==
然后再定义一个secret,如下
secret
通过header中定义的HS256算法以secret为密钥进行加密得到signature
81faa5ef7b7596783cb3ed2f75618def367a9b7f8490047cb12880d895b794eb
此时JWT就生成了,base64(header).base64(payload) .signature
像这样ewogICJ0eXAiOiAidG9rZW7nsbvlnosiLAogICJhbGciOiAi562+5ZCN566X5rOVIgp9.ewogICAgImlhdCI6IOW9k+WJjeaXtumXtCwKICAgICJleHAiOiDov4fmnJ/ml7bpl7QsCiAgICAidWlkIjogIjAwNyIKfQ==.81faa5ef7b7596783cb3ed2f75618def367a9b7f8490047cb12880d895b794eb
当然这种方式不能在token中携带敏感信息,例如密码
0x04 应用
- 单点登陆
Set-Cookie: jwt=yyy.zzz.xxx; HttpOnly; max-age=980000; domain=.taobao.com
- API 调用/授权
https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=xxxx
支付验证(一次性)
串行服务调用
一次性有效,再次生成token时以用户账户和第一次token为key,update该记录来判断
敏感接口多次调用
0x05 代码
生成代码
1 | private static final JWSHeader header=new JWSHeader(JWSAlgorithm.HS256, JOSEObjectType.JWT, null, null, null, null, null, null, null, null, null, null, null); |
校验代码
1 | public static Map<String, Object> validToken(String token) { |
参考:
http://blog.leapoahead.com/2015/09/06/understanding-jwt/
https://github.com/bigmeow/JWT
- Post title:基于token的认证
- Post author:langu_xyz
- Create time:2018-05-18 21:00:00
- Post link:https://blog.langu.xyz/基于token的认证/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.