Spring Boot+redis存儲session,知足集羣部署、分佈式系統的session共享

本文講述spring-boot工程中使用spring-session機制進行安全認證,而且經過redis存儲session,知足集羣部署、分佈式系統的session共享。java

java工程中,說到權限管理和安全認證,咱們首先想到的是Spring Security和Apache Shiro,這二者均能實現用戶身份認證和複雜的權限管理功能。可是若是咱們只是想實現身份認證(如是否登陸、會話是否超時),使用session管理便可知足。本文目錄以下:git

目錄:

  1. 建立spring-boot項目

  2. 用戶管理

  3. 用戶身份認證

  4. spring-session配置

  5. 使用redis共享session


1、建立spring-boot項目

一、工程使用idea+gradle搭建,jdk1.8,spring-boot版本2.0.2.RELEASE,數據庫postgreSQL,持久層spring-data-jpa;
二、新建spring-boot項目,工程type選擇Gradle Project;
三、勾選初始化依賴以下:github


初始化依賴
初始化依賴

建立完成後gradle.build文件內容以下:web

buildscript {
    ext {
        springBootVersion = '2.0.2.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'idea' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' group = 'louie.share' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter-data-jpa') compile('org.springframework.boot:spring-boot-starter-web') runtime('org.springframework.boot:spring-boot-devtools') runtime('org.postgresql:postgresql') testCompile('org.springframework.boot:spring-boot-starter-test') } 

四、application.yml配置數據庫及jparedis

spring:
  datasource:
    driver-class-name: org.postgresql.Driver url: jdbc:postgresql://127.0.0.1:5432/louie data-username: louie password: louie1234 jpa: database: postgresql hibernate: ddl-auto: update 

2、用戶管理

一、建立User實體類spring

import org.hibernate.annotations.GenericGenerator; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import java.io.Serializable; /** * 用戶實體 * @author louie * @date created in 2018-5-12 17:28 */ @Entity @Table(name = "b_id_user") public class User implements Serializable{ @Id @GenericGenerator(name = "idGenerator",strategy = "uuid") @GeneratedValue(generator = "idGenerator") private String id; @NotBlank(message = "account can not be empty") private String account; @NotBlank(message = "password can not be empty") private String password; @NotBlank(message = "name can not be empty") private String name; //省略getter、setter } 

二、用戶服務接口sql

import louie.share.sessionredis.bean.User; /** * 用戶服務接口 * @author louie * @date created in 2018-5-12 17:40 */ public interface UserService { /** * save user * @param user * @return 保存後的用戶信息 */ User saveUser(User user); /** * find user by account * @param account * @return */ User findByAccount(String account); /** * user login * @param account * @param password * @return */ BaseResponse login(String account,String password); } 

這裏省略接口的實現,您能夠訪問個人github和碼雲查看該工程的源代碼(代碼地址見文檔底部)。數據庫

三、用戶管理控制器json

import louie.share.sessionredis.bean.BaseResponse; import louie.share.sessionredis.bean.User; import louie.share.sessionredis.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; /** * 用戶管理相關控制器 * @author louie * @date created in 2018-5-12 17:26 */ @RestController @RequestMapping(value = "/user") public class UserController { @Autowired private UserService userService; /** * save user * @param user * @return */ @RequestMapping(value = "/save",method = RequestMethod.POST) public User save(User user){ return userService.saveUser(user); } /** * find user by account * @param account * @return */ @RequestMapping(value = "/find/{account}",method = RequestMethod.GET) public User find(@PathVariable String account){ return userService.findByAccount(account); } /** * user login * @param account * @param password * @return */ @RequestMapping(value = "/login",method = RequestMethod.POST) public BaseResponse login(String account,String password){ return userService.login(account,password); } } 

四、建立用戶
運行Application類啓動服務,使用postMan訪問http://localhost:8080/user/save服務建立用戶:
安全

建立用戶
建立用戶

 

3、用戶身份認證

一、使用postMan訪問http://localhost:8080/user/login進行用戶登陸校驗:

微信截圖_20180512184322.png-66.2kB
微信截圖_20180512184322.png-66.2kB

 

4、spring-session配置

該部分爲重點內容了,目的是實現訪問資源時的安全認證、超時控制和用戶登出功能。
一、修改用戶登陸login控制,登陸成功後將用戶信息寫入session

/** * user login * @param account * @param password * @return */ @RequestMapping(value = "/login",method = RequestMethod.POST) public BaseResponse login(String account, String password,HttpSession session){ BaseResponse response = userService.login(account,password); if (response.isOk()){ session.setAttribute(session.getId(),response.getData()); } return response; } 

二、新增用戶登出logout功能,將用戶信息移除session

/** * user logout * @param session * @return */ @RequestMapping(value = "/logout") public String logout(HttpSession session){ session.removeAttribute(session.getId()); return "user logout success"; } 

三、設置session過時時間

spring:
  datasource:
    driver-class-name: org.postgresql.Driver url: jdbc:postgresql://127.0.0.1:5432/louie data-username: louie password: louie1234 jpa: database: postgresql hibernate: ddl-auto: update server: servlet: session: timeout: "PT10M" 

如下是爲session有效時長爲10分鐘:


設置session過時時間
設置session過時時間

四、添加攔截器,經過session判斷用戶是否有效

import com.alibaba.fastjson.JSON; import louie.share.sessionredis.bean.BaseResponse; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; /** * @author louie * @date created in 2018-5-12 19:02 */ @Configuration public class SessionCofig implements WebMvcConfigurer{ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new SecurityInterceptor()) //排除攔截 .excludePathPatterns("/user/login") .excludePathPatterns("/user/logout") //攔截路徑 .addPathPatterns("/**"); } @Configuration public class SecurityInterceptor implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { HttpSession session = request.getSession(); if (session.getAttribute(session.getId()) != null){ return true; } response.getWriter().write(JSON.toJSONString( new BaseResponse(){{ setOk(false); setMessage("please login first"); }} )); return false; } } } 

五、使用postMan訪問http://localhost:8080/user/find/101,用戶未登陸,被攔截:

用戶未登陸攔截
用戶未登陸攔截

 

訪問http://localhost:8080/user/login登陸:

用戶登陸
用戶登陸

 

再次訪問訪問http://localhost:8080/user/find/101

登陸後訪問
登陸後訪問

 

5、使用redis存儲session

一、添加依賴

compile('org.springframework.boot:spring-boot-starter-data-redis') compile('org.springframework.session:spring-session-data-redis') 

二、application.yml中添加配置


redis配置
redis配置

源代碼:

spring:
  datasource:
    driver-class-name: org.postgresql.Driver url: jdbc:postgresql://127.0.0.1:5432/louie data-username: louie password: louie1234 jpa: database: postgresql hibernate: ddl-auto: update redis: database: 0 host: localhost port: 6379 password: xonro_vflow session: store-type: redis server: servlet: session: timeout: "PT10M" 

三、啓動redis和application類,用戶登陸,查看redis內容:

debug查看:


debug查看session信息
debug查看session信息

redis內容:


redis內容
redis內容

工程代碼已共享至github和碼雲,歡迎探討學習。


 

相關文章
相關標籤/搜索