jwt与redis,把生成的token放入redis中进行临时存储

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
全局流量管理 GTM,标准版 1个月
简介: jwt与redis,把生成的token放入redis中进行临时存储

jwt与redis,把生成的token放入redis中进行临时存储

简介:本文讲解,如何结合jwt与redis,我们把jwt生成的token存放在redis中。

springboot+jwt的教程可以看这篇文章:

vue与jwt验证

SpringBoot+JWT+Shiro

SpringBoot连接redis

讲解

在上面的文章的基础之上,首先是,我们需要加上一些辅助类,依赖还有配置信息。

文章中的代码可以看这里:https://gitee.com/geek-li-hua/code-in-blog.git

  • ErrorCode 统一错误码处理类
public enum  ErrorCode {
    PARAMS_ERROR(10001,"参数有误"),
    ACCOUNT_PWD_NOT_EXIST(10002,"用户名或密码不存在"),
    NO_PERMISSION(70001,"无访问权限"),
    SESSION_TIME_OUT(90001,"会话超时"),
    NO_LOGIN(90002,"未登录"),;
    private int code;
    private String msg;
    ErrorCode(int code, String msg){
        this.code = code;
        this.msg = msg;
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>

配置文件

加上redis的相关配置文件

# Redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=root@123456
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-wait=-1
spring.redis.jedis.pool.max-idle=500
spring.redis.jedis.pool.min-idle=0
spring.redis.lettuce.shutdown-timeout=0

代码

我们需要知道的是,我们生成的token,对于前端,是存储在localstorage里面的,然后对于后端是存储在redis里面的,所以退出只需要删除redis中的存储就可以了。

首先在需要注入redisTemplate。

@Autowired
private RedisTemplate<String, String> redisTemplate;

然后在login中加入下面代码

import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.springbootjwt.Bean.User;
import com.example.springbootjwt.Config.Result;
import com.example.springbootjwt.Dto.LoginDto;
import com.example.springbootjwt.Service.IUserService;
import com.example.springbootjwt.Utils.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSON;
/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author jakelihua
 * @since 2023-08-14
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private IUserService userService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @PostMapping("/login")
    public Result<Map<String, Object>> login(@RequestBody LoginDto user) {
        // 创建结果对象
        Result<Map<String, Object>> result;
        try {
            // 调用userService的login方法进行用户认证
            User userDB = userService.login(user);
            // 获取用户ID和用户名,并将其放入payload
            Map<String, String> payload = new HashMap<>();
            payload.put("id", userDB.getId().toString());
            payload.put("name", userDB.getUsername());
            // 生成JWT的令牌
            String token = JWTUtils.getToken(payload);
            // 构造成功的结果对象
            result = new Result<>(200, "认证成功");
            result.setData(new HashMap<>());
            result.getData().put("token", token); // 响应token
            redisTemplate.opsForValue().set("TOKEN:" + token, JSON.toJSONString(payload));
        } catch (Exception e) {
            // 构造失败的结果对象
            e.printStackTrace();
            result = Result.fail(500, "账号或密码错误");
        }
        System.out.println(result);
        return result;
    }
    @GetMapping("/index")
    public String index(){
        return "这是主页";
    }
    @PostMapping("/register")
    public Result<Map<String, Object>> register(@RequestBody User user){
        // 创建结果对象
        Result<Map<String, Object>> result;
        User user1 = userService.selectByUsername(user.getUsername());
        if (user1 != null){
            result = Result.fail(405, "用户已存在,请更换用户名");
        } else {
            boolean register = userService.register(user);
            if (register){
                result = new Result(200, "注册成功");
            } else {
                result = Result.fail(500, "注册失败");
            }
        }
        return result;
    }
    @GetMapping("/all/{token}")
    Result<Map<String, Object>> getByAll(@PathVariable String token) {
        List<User> list = userService.list();
        Result<Map<String, Object>> result;
        System.out.println(token);
        try {
            Map<String, Object> map = new HashMap<>();
            // 处理自己的业务逻辑
            // 校验并解析token
            verifyToken(token);
            map.put("data", list);
            // 构造成功的结果对象
            result = new Result<>(200, "请求成功!");
            result.setData(map);
        } catch (Exception e) {
            // 构造失败的结果对象
            result = Result.fail(500, e.getMessage());
        }
        return result;
    }
    private void verifyToken(String token) throws Exception {
        // 校验并解析token
        DecodedJWT verify = JWTUtils.verify(token);
        // 可以在这里添加其他的校验逻辑
        // 打印解析出的用户id和用户名
        log.info("用户id: [{}]", verify.getClaim("id").asString());
        log.info("用户name: [{}]", verify.getClaim("name").asString());
    }
    @GetMapping("/test/{token}")
    public Result<Map<String, Object>> test(@PathVariable String token) {
        // 创建结果对象
        Result<Map<String, Object>> result;
        try {
            Map<String, Object> map = new HashMap<>();
            // 处理自己的业务逻辑
            // 从请求头中获取token
            // 校验并解析token
            DecodedJWT verify = JWTUtils.verify(token);
            // 打印解析出的用户id和用户名
            log.info("用户id: [{}]", verify.getClaim("id").asString());
            log.info("用户name: [{}]", verify.getClaim("name").asString());
            // 构造成功的结果对象
            result = new Result<>(200, "请求成功!");
            result.setData(map);
        } catch (Exception e) {
            // 构造失败的结果对象
            result = Result.fail(500, e.getMessage());
        }
        return result;
    }
}

登录之后,可以看出来,token存储成功了。

  • 对于退出

编写下面这个方法

@GetMapping("/logout/{token}")
    public String logout(@PathVariable String token){
        redisTemplate.opsForValue().getOperations().delete("TOKEN:" + token);
        String value = redisTemplate.opsForValue().get("yourKey");
        System.out.println(value);
        return "退出登录";
    }

  • 对于前端
logout({ commit }) {
      // 清除token并重定向到登录页面
      commit('CLEAR_TOKEN');
      const token = localStorage.getItem('token');
      localStorage.removeItem('token');
      axios.get(`http://localhost:8989/user/logout/${token}`)
      .then(response => {
        console.log("退出成功")
      })
      .catch(error => {
        console.error(error);
      });
      router.push('/');
    },

点击退出之后,就没有了

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
26天前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(一)
数据的存储--Redis缓存存储(一)
60 1
|
26天前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(二)
数据的存储--Redis缓存存储(二)
37 2
数据的存储--Redis缓存存储(二)
|
22天前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
56 6
|
3月前
|
存储 缓存 NoSQL
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
|
2月前
|
存储 中间件 API
ThinkPHP 集成 jwt 技术 token 验证
本文介绍了在ThinkPHP框架中集成JWT技术进行token验证的流程,包括安装JWT扩展、创建Token服务类、编写中间件进行Token校验、配置路由中间件以及测试Token验证的步骤和代码示例。
ThinkPHP 集成 jwt 技术 token 验证
|
19天前
|
JSON NoSQL Java
springBoot:jwt&redis&文件操作&常见请求错误代码&参数注解 (九)
该文档涵盖JWT(JSON Web Token)的组成、依赖、工具类创建及拦截器配置,并介绍了Redis的依赖配置与文件操作相关功能,包括文件上传、下载、删除及批量删除的方法。同时,文档还列举了常见的HTTP请求错误代码及其含义,并详细解释了@RequestParam与@PathVariable等参数注解的区别与用法。
|
19天前
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
21 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
2月前
|
JSON 安全 数据安全/隐私保护
从0到1搭建权限管理系统系列三 .net8 JWT创建Token并使用
【9月更文挑战第22天】在.NET 8中,从零开始搭建权限管理系统并使用JWT(JSON Web Tokens)创建Token是关键步骤。JWT是一种开放标准(RFC 7519),用于安全传输信息,由头部、载荷和签名三部分组成。首先需安装`Microsoft.AspNetCore.Authentication.JwtBearer`包,并在`Program.cs`中配置JWT服务。接着,创建一个静态方法`GenerateToken`生成包含用户名和角色的Token。最后,在控制器中使用`[Authorize]`属性验证和解析Token,从而实现身份验证和授权功能。
101 3
|
2月前
|
存储 NoSQL Redis
2)Redis 的键值对长什么样子,又是怎么存储的?
2)Redis 的键值对长什么样子,又是怎么存储的?
34 0
|
3月前
|
存储 消息中间件 NoSQL
Redis命令详解以及存储原理
Redis命令详解以及存储原理