SPRING-分佈式環境下Springboot的登錄如何保證session共享

一個很簡單的項目,需要介入到權限,於是我直接新建了幾張權限用戶表。由於該功能僅僅給後臺的幾個工作人員使用,登錄用的很簡單。在測試環境一直部署了一臺,所以直接用的sessionId是沒有問題的。但是部署到了正式環境,由於是分佈式部分,平臺直接部署了2個實例,這樣用sessionId來判斷是否登錄就有問題了。
怎麼解決,用spring-session-data-redis。該包是基於redis的。

引入依賴

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

增加配置代碼

package com.dashboard.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
 * 配置在redis中共享session
 */
@Configuration
/**
 * 設置session的默認在redis中的存活時間
 */
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class SessionConfig {
}
package com.dashboard.auth;

import com.dashboard.config.SessionConfig;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;

/**
 * 初始化
 */
public class SessionInitializer extends AbstractHttpSessionApplicationInitializer {
    public SessionInitializer() {
        super(SessionConfig.class);
    }
}
##redis的配置
spring.redis.sentinel.master=redis1
spring.redis.sentinel.nodes=地址:2680,地址:2630
spring.redis.timeout=6000
spring.redis.database=0
spring.redis.lettuce.pool.max-active=16
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.shutdown-timeout=100ms

增加登錄/校驗代碼

    /**
     * 
     * 登錄-生成sessionId
     * @return
     */
    @PostMapping("/login")
    public Result<AuthUser> login(HttpServletRequest request, String username, String password) {
        if (StringUtils.isBlank(username)||StringUtils.isBlank(password)){
            return Result.ofFail(-1, "Invalid username or password");
        }
   
            AuthUser authUser= new AuthUser();
            authUser.setId(22222);
            String sessionId= request.getSession().getId(); 
            stringRedisTemplate.opsForValue().set(sessionId, gson.toJson(authUser),30, TimeUnit.MINUTES);
            return Result.ofSuccess();
        }else {
            return Result.ofFail(-1, "Invalid username or password");
        }
}
 /**
     * 
     * 通過獲取sessionId來判斷是否登錄
     * @return
     */
 public AuthUser getAuthUser( HttpServletRequest request) {
        String sessionId= request.getSession().getId();
        if (StringUtils.isNotBlank(sessionId)){
            String str = stringRedisTemplate.opsForValue().get(sessionId);
            if (StringUtils.isNotBlank(str)){
                return new Gson().fromJson(str, AuthUser.class);
            }else {
                return null;
            }
        }else {
            return null;
        }
    }

分佈式環境下session是否一致

在這裏插入圖片描述
部署了多個實例,多次刷新列表,裏面的SESSION一樣,分佈式環境下,session共享成功。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章