亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot+SpringSession+Redis實現(xiàn)session共享及唯一登錄示例

 更新時間:2021年04月29日 16:45:18   作者:保爾-科查筋  
這篇文章主要介紹了SpringBoot+SpringSession+Redis實現(xiàn)session共享及唯一登錄示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

最近在學習springboot,session這個點一直困擾了我好久,今天把這些天踩的坑分享出來吧,希望能幫助更多的人。

一、pom.xml配置 

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

二、application.properties的redis配置

#redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
#超時一定要大于0
spring.redis.timeout=3000
spring.session.store-type=redis

在配置redis時需要確保redis安裝正確,并且配置notify-keyspace-events Egx,spring.redis.timeout設置為大于0,我當時這里配置為0時springboot時啟不起來。

三、編寫登錄狀態(tài)攔截器RedisSessionInterceptor

//攔截登錄失效的請求
public class RedisSessionInterceptor implements HandlerInterceptor
{
    @Autowired
    private StringRedisTemplate redisTemplate;
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
    {
        //無論訪問的地址是不是正確的,都進行登錄驗證,登錄成功后的訪問再進行分發(fā),404的訪問自然會進入到錯誤控制器中
        HttpSession session = request.getSession();
        if (session.getAttribute("loginUserId") != null)
        {
            try
            {
                //驗證當前請求的session是否是已登錄的session
                String loginSessionId = redisTemplate.opsForValue().get("loginUser:" + (long) session.getAttribute("loginUserId"));
                if (loginSessionId != null && loginSessionId.equals(session.getId()))
                {
                    return true;
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
 
        response401(response);
        return false;
    }
 
    private void response401(HttpServletResponse response)
    {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
 
        try
        {
            response.getWriter().print(JSON.toJSONString(new ReturnData(StatusCode.NEED_LOGIN, "", "用戶未登錄!")));
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
    {
 
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception
    {
 
    }
}

四、配置攔截器

@Configuration
public class WebSecurityConfig extends WebMvcConfigurerAdapter
{
    @Bean
    public RedisSessionInterceptor getSessionInterceptor()
    {
        return new RedisSessionInterceptor();
    }
 
    @Override
    public void addInterceptors(InterceptorRegistry registry)
    {
        //所有已api開頭的訪問都要進入RedisSessionInterceptor攔截器進行登錄驗證,并排除login接口(全路徑)。必須寫成鏈式,分別設置的話會創(chuàng)建多個攔截器。
        //必須寫成getSessionInterceptor(),否則SessionInterceptor中的@Autowired會無效
        registry.addInterceptor(getSessionInterceptor()).addPathPatterns("/api/**").excludePathPatterns("/api/user/login");
        super.addInterceptors(registry);
    }
}

五、登錄控制器

@RestController
@RequestMapping(value = "/api/user")
public class LoginController
{
    @Autowired
    private UserService userService;
 
    @Autowired
    private StringRedisTemplate redisTemplate;
 
    @RequestMapping("/login")
    public ReturnData login(HttpServletRequest request, String account, String password)
    {
        User user = userService.findUserByAccountAndPassword(account, password);
        if (user != null)
        {
            HttpSession session = request.getSession();
            session.setAttribute("loginUserId", user.getUserId());
            redisTemplate.opsForValue().set("loginUser:" + user.getUserId(), session.getId());
 
            return new ReturnData(StatusCode.REQUEST_SUCCESS, user, "登錄成功!");
        }
        else
        {
            throw new MyException(StatusCode.ACCOUNT_OR_PASSWORD_ERROR, "賬戶名或密碼錯誤!");
        }
    }
 
    @RequestMapping(value = "/getUserInfo")
    public ReturnData get(long userId)
    {
        User user = userService.findUserByUserId(userId);
        if (user != null)
        {
            return new ReturnData(StatusCode.REQUEST_SUCCESS, user, "查詢成功!");
        }
        else
        {
            throw new MyException(StatusCode.USER_NOT_EXIST, "用戶不存在!");
        }
    }
}

六、效果

我在瀏覽器上登錄,然后獲取用戶信息,再在postman上登錄相同的賬號,瀏覽器再獲取用戶信息,就會提示401錯誤了,瀏覽器需要重新登錄才能獲取得到用戶信息,同樣,postman上登錄的賬號就失效了。

瀏覽器:

postman:

七、核心原理詳解

分布式session需要解決兩個難點:1、正確配置redis讓springboot把session托管到redis服務器。2、唯一登錄。

1、redis:

redis需要能正確啟動到出現(xiàn)如下效果才證明redis正常配置并啟動

同時還要保證配置正確

@EnableCaching
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 30)//session過期時間(秒)
@Configuration
public class RedisSessionConfig
{
    @Bean
    public static ConfigureRedisAction configureRedisAction()
    {
        //讓springSession不再執(zhí)行config命令
        return ConfigureRedisAction.NO_OP;
    }
}

springboot啟動后能在redis上查到緩存的session才能說明整個redis+springboot配置成功!

2、唯一登錄:

1、用戶登錄時,在redis中記錄該userId對應的sessionId,并將userId保存到session中。

HttpSession session = request.getSession();
session.setAttribute("loginUserId", user.getUserId());
redisTemplate.opsForValue().set("loginUser:" + user.getUserId(), session.getId());

2、訪問接口時,會在RedisSessionInterceptor攔截器中的preHandle()中捕獲,然后根據(jù)該請求發(fā)起者的session中保存的userId去redis查當前已登錄的sessionId,若查到的sessionId與訪問者的sessionId相等,那么說明請求合法,放行。否則拋出401異常給全局異常捕獲器去返回給客戶端401狀態(tài)。

唯一登錄經(jīng)過我的驗證后滿足需求,暫時沒有出現(xiàn)問題,也希望大家能看看有沒有問題,有的話給我點好的建議!

到此這篇關于SpringBoot+SpringSession+Redis實現(xiàn)session共享及唯一登錄示例的文章就介紹到這了,更多相關SpringBoot 唯一登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Docker使用 Maven 插件構建鏡像的方法

    Docker使用 Maven 插件構建鏡像的方法

    本篇文章主要介紹了Docker使用 Maven 插件構建鏡像的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • Java將字符串String轉換為整型Int的兩種方式

    Java將字符串String轉換為整型Int的兩種方式

    這篇文章主要介紹了Java如何將字符串String轉換為整型Int,在 Java 中要將 String 類型轉化為 int 類型時,需要使用 Integer 類中的 parseInt() 方法或者 valueOf() 方法進行轉換,本文通過實例代碼給大家詳細講解,需要的朋友可以參考下
    2023-04-04
  • J2SE基礎之在Eclipse中運行hello world

    J2SE基礎之在Eclipse中運行hello world

    本文的內(nèi)容非常的簡單,跟隨世界潮流,第一個Java程序輸出“Hell World!”。希望大家能夠喜歡
    2016-05-05
  • Java?Http請求方式之RestTemplate常用方法詳解

    Java?Http請求方式之RestTemplate常用方法詳解

    這篇文章主要為大家介紹了Java?Http請求方式之RestTemplate常用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Java全面分析面向對象之多態(tài)

    Java全面分析面向對象之多態(tài)

    多態(tài)就是指程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時并不確定,而是在程序運行期間才確定,即一個引用變量到底會指向哪個類的實例對象,該引用變量發(fā)出的方法調(diào)用到底是哪個類中實現(xiàn)的方法,必須在由程序運行期間才能決定
    2022-04-04
  • java設計模式之單例模式

    java設計模式之單例模式

    這篇文章主要為大家詳細介紹了java設計模式之單例模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • springboot中的springSession的存儲和獲取實現(xiàn)

    springboot中的springSession的存儲和獲取實現(xiàn)

    這篇文章主要介紹了springboot中的springSession的存儲和獲取實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • Bean的管理與SpringBoot自動裝配原理解讀

    Bean的管理與SpringBoot自動裝配原理解讀

    在SpringBoot項目中,啟動時自動創(chuàng)建IOC容器并初始化bean對象,支持通過依賴注入獲取,Bean可以通過name或類型獲取,支持單例和非單例等多種作用域,對于第三方Bean,推薦在配置類中用@Bean標識方法進行定義
    2024-11-11
  • idea微服務項目服務如何顯示在同一窗口

    idea微服務項目服務如何顯示在同一窗口

    本文介紹了如何在微服務項目導入時將所有服務加入同一窗口中,解決啟動項目服務時顯示不全的問題,通過點擊左上角的View,選擇ToolWindows,然后選擇Services,使用快捷鍵Alt+8,選擇Spring Boot,就可以將所有服務加到同一窗口中
    2025-02-02
  • 提高開發(fā)效率Live?Templates使用技巧詳解

    提高開發(fā)效率Live?Templates使用技巧詳解

    這篇文章主要為大家介紹了提高開發(fā)效率Live?Templates使用技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01

最新評論