目录
一、什么是前后端分离
二、jwt起源
三、token认证机制
四、jwt构成
头部header
载荷payload
签证 signature
五、如何应用
第一小节,我们先对一些背景和相关术语进行说明。
用通俗的话讲就是:前端开发人员做页面样式的开发,后端开发人员处理功能逻辑开发,互不干扰各做各的部分,最终后端开发人员通过协商好的接口协议(一般是json格式)提供给前端开发人员数据,进行页面数据渲染。
前后端分离是目前热门的开发方式,大部分互联网都会采用前后端分离的方式开发。它的优点也很明显,相对于以往传统的单体结构系统,前后端耦合度降低,工作效率得到明显的提高。同时随着vue等一些前端技术栈越来越丰富,前后端开发的模式变得越来越流行。
在传统的单体结构系统中,一般会使用session认证,这是一种基于服务器端的认证方式,一般服务器存储一份用户登录的信息到内存,并通过前端cookie技术,使应用系统能识别请求来自哪个用户。
这样的弊端也很明显,因为服务器要对每一个认证用户都需要保存一份信息,所以服务端的开销会明显增大。其次不便于扩展,特别在分布式的架构上,为了确保用户的请求能到达同一认证服务器上,相应的限制了负载均衡器的能力。
基于以上的问题,我们一般采用token认证机制来解决。
token认证机制,它是无状态的,它不需要在服务端保存用户的认证信息。这就意味着基于token认证机制的应用系统不需要去考虑用户在哪一台服务器认证过了,这就有利于应用的扩展。
一般的token认证机制如下:
jwt是由三段信息构成:第一部分为头部(header),第二部分为载荷(payload),第三部分是签证(signature)。
jwt字符串样例:
//每个小圆点间为一部分,一共是三段内容拼接而成
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiMTIzNDU2IiwidXNlcl9uYW1lIjoi5byg5LiJIiwiZXhwIjoxNjU0NTI2MDU5fQ.MCuHhUOoRkMeabCk2SlfubDAL7ZgOopn7nti5QDaEhY
jwt的头部有两部分信息:
样例中的头部信息
{
"typ": "JWT",
"alg": "HS256"
}
载荷就是存放有效信息的地方。这些信息包含三个部分:
样例中的载荷信息,定义了用户id、用户姓名、还携带了一个过期时间。
{
"user_id": "123456",
"user_name": "张三",
"exp": 1654526059
}
*注意:因为密文可通过base64解密,所以载荷中不要存放敏感信息,如用户密码、身份证等。
jw签证信息由三部分组成:
这个部分是由base64加密后的header和base64加密后的payload,然后通过'.'连接组成的字符串,最后通过header中声明的加密方式进行加盐secret
组合加密得出。
需在项目pom.xml引入jwt依赖包
com.auth0
java-jwt
3.19.1
服务器端生成jwt样例
//密钥secret
String JWT_USER_AUTH_SECRET = "qwerasdf123";
JWTCreator.Builder builder = JWT.create();
//添加claim
builder.withClaim("user_id", "123456");
builder.withClaim("user_name", "张三");
//设置JWT令牌的过期时间为一天
Calendar instance = Calendar.getInstance();
instance.add(Calendar.SECOND, 1 * 86400);
builder.withExpiresAt(instance.getTime());
//生成JWT
String token = builder.sign(Algorithm.HMAC256(JWT_USER_AUTH_SECRET));
System.out.println(token);
前端开发调用接口时在请求头里加入Authorization
,并加上Bearer
标注
fetch('api/user/123456', {
headers: {
'Authorization': 'Bearer ' + token
}
})