1.token的用处:
前端项目中的token处理是为了保证用户的身份验证和安全性。一般来说,前端会在用户登录成功后,将后端返回的token存储在本地,然后在每次请求时将token加入请求头中,后端会验证token的有效性。如果token过期或者无效,前端需要进行相应的处理,比如清除本地存储的token并跳转到登录页。在Vue项目中,可以使用axios拦截器来实现token的处理,具体可以参考引用中的代码示例。此外,为了更好地管理token,可以使用Vuex来存储和管理token。
2.如何处理:
1.获取token:
通过cookie
private String getUserCookieToken(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (cookies == null || cookies.length == 0) {
return null;
}
for (Cookie cookie : cookies) {
String name = cookie.getName();
if (name.equals("token")) {
return cookie.getValue();
}
}
return null;
}
通过request
String token = request.getHeader("token");
log.info("get token from header:{}", token);
if (token == null) {
token = getUserCookieToken(request);
log.info("get token from cookie:{}", token);
}
if (token == null) {
token = request.getParameter("token");
}
2.token的存放位置
它在用户登录成功之后会返回给客户端,客户端主要以下几种存储方式:
1、存储在localStorage中,每次调用接口的时候都把它当成一个字段传给后台
2、存储在cookie中,让它自动发送,不过缺点就是不能跨域
3、拿到之后存储在localStorage中,每次调用接口的时候放在HTTP请求头的Authorization字段里面。token 在客户端一般存放于localStorage、cookie、或sessionStorage中。
3.生成token
jwt方法
什么是jwt:
JWT 即Json Web Token,将用户登录状态以及数据用加密的json格式存储在客户端,服务端可以完全依靠这个字符串认定用户身份。简单来说,这是一种用户身份认证的解决方案。
jwt的构成:
一个JWT实际上就是一个字符串,由三部分组成分别是:
header(头部)
payload(载荷)
signature(签名)
结构如下:header.payload.signature
第一部分:header(头部)
header(头部)的信息指定了其Token类型和所使用的加密算法。
{
"typ": "JWT",
"alg": "HS256"
}
然后将头部进行base64编码(该加密是可以解码的),构成了第一部eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
第二部分:payload(载荷)
payload(载荷)信息存放的是Claims声明信息。载荷其实就是自定义的数据,一般存储用户Id,过期时间等信息。也就是JWT的核心所在,因为这些数据就是使后端知道此token是哪个用户已经登录的凭证。而且这些数据是存在token里面的,由前端携带,所以后端几乎不需要保存任何数据。
{
'id': user.id,
'username': user.username,
‘exp’: time.time() + 300, #过期时间
}
然后将其进行base64编码,得到Jwt的第二部分:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZvaG4gRGdWV9
第三部分:signature(签名)
signature(签名)需要使用编码后的header和payload以及一个秘钥,使用header中声明的编码方式进行加盐secret组合加密,然后就构成了jwt的第三部分:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZvaG4gRGdWV9
最后将 token = header + '.'+ payload +'.'+ signature,生成token
4.token过期处理方案
1、刷新令牌(Refresh Token)
在用户登录时,除了发放一个访问令牌(Access Token)以外,再发放一个刷新令牌(Refrsh Token)。
访问令牌的有效期比较短,刷新令牌的有效期比较长。
当访问令牌过期时,使用刷新令牌向服务器请求新的访问令牌。如果刷新令牌也过期,则跳转回登录界面。
这种方式的优点是可以避免用户频繁登录,但需要妥善保管刷新令牌,因为它的安全性比访问令牌更高。
2、滑动窗口
用户每次使用使用访问令牌时,服务器都会更新访问令牌的过期时间。
这种方式的优点是用户只要频繁访问,就不需要登录,但可能会增加服务器负担。
3、重新登录
当访问令牌过期时,跳转回登录界面,让用户重新登录。这是最简单的一种方式,但可能会影响用户体验。
示例代码:
const jwt = require('jsonwebtoken');
const secret = 'your-secret-key';
const refreshSecret = 'your-refresh-secret-key';
// 用户登录
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 验证用户名和密码
const user = authenticate(username, password);
if (user) {
// 创建 JWT
const token = jwt.sign({ id: user.id }, secret, { expiresIn: '1h' });
const refreshToken = jwt.sign({ id: user.id }, refreshSecret, { expiresIn: '7d' });
// 将 JWT 和刷新令牌发送给用户
res.json({ token, refreshToken });
} else {
res.status(401).send('Invalid credentials');
}
});
// 刷新令牌
app.post('/refresh', (req, res) => {
const { refreshToken } = req.body;
// 验证刷新令牌
jwt.verify(refreshToken, refreshSecret, (err, decoded) => {
if (err) {
res.status(401).send('Invalid refresh token');
} else {
// 创建新的 JWT
const newToken = jwt.sign({ id: decoded.id }, secret, { expiresIn: '1h' });
res.json({ token: newToken });
}
});
});