欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Redis實(shí)現(xiàn)JWT令牌主動失效機(jī)制

 更新時(shí)間:2024年08月12日 10:47:05   作者:記得開心一點(diǎn)嘛  
JWT是一種輕量級的身份驗(yàn)證和授權(quán)機(jī)制,它是一種 JSON 格式的數(shù)據(jù)串,通常用于客戶端和服務(wù)端之間的單點(diǎn)登錄(Single Sign-On, SSO)場景,本文給大家介紹了如何使用Redis來實(shí)現(xiàn)JWT令牌主動失效機(jī)制,需要的朋友可以參考下

一.實(shí)現(xiàn)思路:

  • 登錄成功后,給瀏覽器響應(yīng)令牌的同時(shí),把該令牌存儲到Redis中
  • LoginInterceptor攔截器中,需要驗(yàn)證瀏覽器攜帶的令牌,并同時(shí)需要獲取到Redis中的存儲的與之相同的令牌,如果獲取到證明令牌有效,如果沒有獲取到則令牌無效
  • 當(dāng)用戶修改密碼成功后,刪除Redis中存儲的舊令牌

二.實(shí)現(xiàn)代碼解析:

1.首先配置Redis的相關(guān)配置文件:

(1)pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

(2)在application.yml中配置相關(guān)信息:

spring:
  data:
    redis:
      host: localhost
      port: 6379
      password: *******  #Redis的密碼
      database: ***      #指定使用哪個(gè)數(shù)據(jù)源(可不寫,但默認(rèn)是DB0)

(3)編寫配置類,創(chuàng)建RedisTemplate對象:

我們使用RedisTemplate這個(gè)類對象內(nèi)封裝的方法來操作Redis,所以我們在配置類內(nèi)創(chuàng)建RedisTemplate并用Bean注解將其交給Spring容器管理。

@Configuration
@Slf4j
public class RedisConfiguration {
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        log.info("開始創(chuàng)建Redis模板對象...0");
        RedisTemplate redisTemplate = new RedisTemplate();
        //設(shè)置redis的連接工廠對象
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //設(shè)置redis key的序列化器,這里反應(yīng)的是Redis圖形化工具上value值的不同
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}

2.登錄成功后,給瀏覽器響應(yīng)令牌的同時(shí),把該令牌存儲到Redis中:

@RestController
@RequestMapping("/user")
@Validated
public class UserController {
 
    @Autowired
    private UserService userService;
    @Autowired
    private RedisTemplate redisTemplate;
 
    /**
     * 用戶登錄
     * @param username
     * @param password
     * @return
     */
    @PostMapping("/login")
    public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username ,@Pattern(regexp = "^\\S{5,16}$") String password){
        //根據(jù)username查詢用戶
        User loginUser = userService.findByUserName(username);
        //判斷是否存在
        if(loginUser == null){
            return Result.error("用戶名錯(cuò)誤");
        }
        //判斷密碼是否正確
        if(Md5Util.getMD5String(password).equals(loginUser.getPassword())){
            //登錄成功,創(chuàng)建JWT令牌
            Map<String,Object> claims = new HashMap<>();
            claims.put("id",loginUser.getId());
            claims.put("username",loginUser.getUsername());
            String token = JwtUtil.genToken(claims);
            //將token存儲到redis中
            redisTemplate.opsForValue().set(token,token,1, TimeUnit.HOURS);//key,value,時(shí)間值,時(shí)間單位
            return Result.success(token);
        }
        return Result.error("密碼錯(cuò)誤");
    }
}

3.LoginInterceptor攔截器中,需要驗(yàn)證瀏覽器攜帶的令牌,并同時(shí)需要獲取到Redis中的存儲的與之相同的令牌:

package com.itheima.bigdealboot.interceptors;
 
 
import com.itheima.bigdealboot.utils.JwtUtil;
import com.itheima.bigdealboot.utils.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
 
import java.util.Map;
//攔截器
@Component
public class LoginInterceptor implements HandlerInterceptor {
 
    @Autowired
    private RedisTemplate redisTemplate;
 
    @Override
    public boolean preHandle(HttpServletRequest request , HttpServletResponse response , Object handle) throws Exception{
        String token = request.getHeader("Authorization"); //Authorization為請求頭的名字
        try {
            //從Redis中國獲取相同的token
            String redisToken = (String) redisTemplate.opsForValue().get(token);
            if(redisToken == null){
                //token已經(jīng)失效,拋出異常
                throw new RuntimeException();
            }
            //令牌驗(yàn)證
            Map<String,Object> claims = JwtUtil.parseToken(token);
            //線程開辟空間存儲
            ThreadLocalUtil.set(claims);
            //放行
            return true;
        }catch (Exception e){
            //http響應(yīng)狀態(tài)碼為401在·
            response.setStatus(401);
            //不放行
            return false;
        }
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //清空線程數(shù)據(jù)
        ThreadLocalUtil.remove();
    }
}

4.當(dāng)用戶修改密碼成功后,刪除Redis中存儲的舊令牌:

@RestController
@RequestMapping("/user")
@Validated
public class UserController {
 
    @Autowired
    private UserService userService;
    @Autowired
    private RedisTemplate redisTemplate;
 
    @PatchMapping("/updatePwd")
    public Result updatePwd(@RequestBody Map<String,String> params,@RequestHeader("Authorization") String token){
        //校驗(yàn)參數(shù)
        String oldPwd = params.get("old_pwd");
        String newPwd = params.get("new_pwd");
        String rePwd = params.get("re_pwd");
        if(StringUtils.hasLength(oldPwd) || StringUtils.hasLength(newPwd) || StringUtils.hasLength(rePwd)){
            return Result.error("缺少必要參數(shù)");
        }
        //校驗(yàn)
        Map<String,Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        User loginUser = userService.findByUserName(username);
        if(!loginUser.getPassword().equals(Md5Util.getMD5String(oldPwd))){
            return Result.error("原密碼填寫不正確");
        }
        if(!rePwd.equals(newPwd)){
            return Result.error("兩次填寫的新密碼不一樣");
        }
        //更新密碼
        userService.updatePwd(newPwd);
        //刪除redis中對應(yīng)的token
        redisTemplate.opsForValue().getOperations().delete(token);
        return Result.success();
    }
}

到此這篇關(guān)于使用Redis實(shí)現(xiàn)JWT令牌主動失效機(jī)制的文章就介紹到這了,更多相關(guān)Redis JWT主動失效機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Redis用鏈表實(shí)現(xiàn)消息隊(duì)列

    詳解Redis用鏈表實(shí)現(xiàn)消息隊(duì)列

    Redis有兩種方式實(shí)現(xiàn)消息隊(duì)列,一種是用Redis自帶的鏈表數(shù)據(jù)結(jié)構(gòu),另一種是用Redis發(fā)布/訂閱模式實(shí)現(xiàn),這篇文章先介紹鏈表實(shí)現(xiàn)消息隊(duì)列,有需要的朋友們可以參考借鑒。
    2016-09-09
  • Redis數(shù)據(jù)一致性詳解

    Redis數(shù)據(jù)一致性詳解

    文章主要討論了分布式系統(tǒng)中的數(shù)據(jù)一致性模型、緩存使用場景以及數(shù)據(jù)同步策略,一致性模型包括強(qiáng)一致性、弱一致性和最終一致性,緩存使用場景主要在高并發(fā)讀取數(shù)據(jù)時(shí)提升性能,數(shù)據(jù)同步策略分為先刪除緩存再更新數(shù)據(jù)庫和先更新數(shù)據(jù)庫再刪除緩存兩種
    2024-11-11
  • 淺談Redis緩存更新策略

    淺談Redis緩存更新策略

    這篇文章主要介紹了Redis緩存更新策略的相關(guān)資料,講解的十分細(xì)致,有需要的小伙伴可以參考下
    2022-08-08
  • Redis數(shù)據(jù)庫的數(shù)據(jù)傾斜詳解

    Redis數(shù)據(jù)庫的數(shù)據(jù)傾斜詳解

    Redis,英文全稱是Remote Dictionary Server(遠(yuǎn)程字典服務(wù)),是一個(gè)開源的使用ANSI C語言編寫、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫,需要的朋友可以參考下
    2023-07-07
  • redis簡介_動力節(jié)點(diǎn)Java學(xué)院整理

    redis簡介_動力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了redis簡介,Redis是一個(gè)開源的,先進(jìn)的 key-value 存儲可用于構(gòu)建高性能,可擴(kuò)展的 Web 應(yīng)用程序的解決方案,有興趣的可以了解一下
    2017-08-08
  • Redis底層類型之json命令使用

    Redis底層類型之json命令使用

    這篇文章主要為大家介紹了Redis底層類型之json命令使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • 如何高效使用Redis作為LRU緩存

    如何高效使用Redis作為LRU緩存

    這篇文章主要介紹了如何高效使用Redis作為LRU緩存,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Redis高可用部署架構(gòu)的實(shí)現(xiàn)

    Redis高可用部署架構(gòu)的實(shí)現(xiàn)

    本文主要介紹了Redis高可用部署架構(gòu)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • Redis配置文件redis.conf詳細(xì)配置說明

    Redis配置文件redis.conf詳細(xì)配置說明

    本文列出了Redis的配置文件redis.conf的各配置項(xiàng)的詳細(xì)說明,簡單易懂
    2018-03-03
  • 基于Redis分布式BitMap的應(yīng)用分析

    基于Redis分布式BitMap的應(yīng)用分析

    這篇文章主要介紹了基于Redis分布式BitMap的應(yīng)用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03

最新評論