token是什么?
Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
token主要有两个作用
1.防止表单重复提交。
防止表单重复提交一般还是使用前后端都限制的方式。比如:在前端点击提交之后,将按钮置为灰色,不可再次点击,然后客户端和服务端的token各自独立存储,客户端存储在Cookie或者Form的隐藏域中,服务端存储在Session或者其他缓存系统中。
2.用来作身份验证。(流程)
① 客户端使用用户名跟密码请求登录;
②通过ajax向后端发送请求;
③服务端收到请求,去验证用户名与密码;
④验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端;
⑤客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里;
⑥客户端每次向服务端请求资源的时候需要带着服务端签发的 Toke(不管是你自己写的)它都要通过ajax向后端发送请求,这时服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
如何创建?
package com.ruoyi.common.utils.uuid;
/**
* ID生成器工具类
*
* @author ruoyi
*/
public class IdUtils
{
/**
* 获取随机UUID
*
* @return 随机UUID
*/
public static String randomUUID()
{
return UUID.randomUUID().toString();
}
/**
* 简化的UUID,去掉了横线
*
* @return 简化的UUID,去掉了横线
*/
public static String simpleUUID()
{
return UUID.randomUUID().toString(true);
}
/**
* 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID
*
* @return 随机UUID
*/
public static String fastUUID()
{
return UUID.fastUUID().toString();
}
/**
* 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID
*
* @return 简化的UUID,去掉了横线
*/
public static String fastSimpleUUID()
{
return UUID.fastUUID().toString(true);
}
}
创建令牌
/**
* 创建令牌
*
* @param loginUser 用户信息
* @return 令牌
*/
public String createToken(LoginUser loginUser)
{
//生成uuid
String token = IdUtils.fastUUID();
//设置用户代理信息
loginUser.setToken(token);
//刷新令牌有效期
setUserAgent(loginUser);
refreshToken(loginUser);
Map<String, Object> claims = new HashMap<>();
claims.put(Constants.LOGIN_USER_KEY, token);
//从数据声明生成令牌
return createToken(claims);
}
设置用户代理信息
/**
* 设置用户代理信息
*
* @param loginUser 登录信息
*/
public void setUserAgent(LoginUser loginUser)
{
UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = IpUtils.getIpAddr();
loginUser.setIpaddr(ip);
loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
loginUser.setBrowser(userAgent.getBrowser().getName());
loginUser.setOs(userAgent.getOperatingSystem().getName());
}
刷新令牌有效期
/**
* 刷新令牌有效期
*
* @param loginUser 登录信息
*/
public void refreshToken(LoginUser loginUser)
{
String authId=userService.queryAuthId(loginUser.getUsername());
loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
loginUser.setAuthId(authId);
// 根据uuid将loginUser缓存
String userKey = getTokenKey(loginUser.getToken());
redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
}
从数据声明生成令牌
/**
* 从数据声明生成令牌
*
* @param claims 数据声明
* @return 令牌
*/
private String createToken(Map<String, Object> claims)
{
String token = Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS512, secret).compact();
return token;
}