1.Token
token:服务端生成的一串字符串,可以解决频繁登录的问题
它作为客户端进行请求的一个令牌:
第一次登录后,服务器生成一个token返回给客户端;
客户端只需要带上token来请求数据即可,无需再次带上用户名和密码
2.使用目的
为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮
3.Token存放在客户端

服务端生成的Token

存放在客户端的Token
1.JWT的pom包
-
- <dependency>
- <groupId>io.jsonwebtokengroupId>
- <artifactId>jjwtartifactId>
- <version>0.9.1version>
- dependency>
2.JWT工具类
- private static final String jwtToken = "xiaosuda"; //C部分;签名
-
- //生成Token:通过UserId创建Token
- public static String createToken(Long userId){
- Map
claims = new HashMap<>(); - claims.put("userId",userId);
-
- JwtBuilder jwtBuilder = Jwts.builder()
- .signWith(SignatureAlgorithm.HS256, jwtToken) //A部分;表头
- .setClaims(claims) //B部分;负载
- .setIssuedAt(new Date())
- .setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000));
- String token = jwtBuilder.compact();
- return token;
- }
-
- //解析Token
- public static Map
checkToken(String token){ - try {
- Jwt parse = Jwts.parser().setSigningKey(jwtToken).parse(token);
- return (Map
) parse.getBody(); - }catch (Exception e){
- e.printStackTrace();
- }
- return null;
- }
这里解析token可以更简单的写直接返回clams获得各种信息,因为我后面还做了封装
3.登录生成token逻辑
- @Override
- public Result login(LoginParams loginParams) {
- String account = loginParams.getAccount(); //拿到账号
- String password = loginParams.getPassword(); //拿到密码
- String slat = loginParams.getSlat(); //拿到加密盐
-
- //根据用户名和密码取user表中查询,查询是否存在
- if (StringUtils.isBlank(account)||StringUtils.isBlank(password)){
- return Result.fail(ErrorCode.PARAMS_ERROR.getCode(),ErrorCode.PARAMS_ERROR.getMsg());
- }
-
- password= DigestUtils.md5Hex(password + slat);
- SysUser sysUser = sysUserService.findUser(account,password);
- //每次登录生成新的token
- String token = JWTUtils.createToken(sysUser.getId());
- System.out.println("=================================");
- System.out.println("第一次登陆的的token: "+token);
- System.out.println("=================================");
- return Result.success(token);
- }

这样登入成功后客户端会存放一个token
- /*
- 登录后用户:验证token是否合法的方法
- */
- @Override
- public SysUser checkToken(String token) {
- //判断是否为空
- if (StringUtils.isBlank(token)){
- System.out.println("前端没有传来token");
- return null;
- }
-
- Map
stringObjectMap = JWTUtils.checkToken(token); - //解析是否成功
- if (stringObjectMap == null){
- System.out.println("token解析未成功");
- return null;
- }
-
- String userJson = redisTemplate.opsForValue().get("TOKEN_" + token);
- //Redis是否校验成功
- if (StringUtils.isBlank(userJson)){
- System.out.println("redis中token不正确");
- return null;
- }
-
- SysUser sysUser = JSON.parseObject(userJson, SysUser.class);
-
- return sysUser;
- }
这里对校验token进行了进一步封装,原本逻辑是直接调用JWT工具类中的checktoken生成claims
- @Override
- public Result findUserByToken(String token) {
-
- //校验失败:通过 loginService.checkToken 的方法实现以上三个检查条件
- SysUser sysUser = loginService.checkToken(token);
-
- if (sysUser == null){
- return
- Result.fail(ErrorCode.TOKEN_ERROR.getCode(),ErrorCode.TOKEN_ERROR.getMsg());
- }
-
- LoginUserVo loginUserVo = new LoginUserVo();
- loginUserVo.setId(String.valueOf(sysUser.getId()));
- loginUserVo.setNickname(sysUser.getNickname());
- loginUserVo.setAvatar(sysUser.getAvatar());
- loginUserVo.setAccount(sysUser.getAccount());
-
- return Result.success(loginUserVo); //验证成功
- }