在一般的傳統下最簡單的方法就是 跟伺服器 登入帳號密碼就取得一個 key
然後伺服器返回 一個 hash 然後我們的 就可以 照著這個 key 去判斷到底是
不是維持這組帳號 是不是 中斷,然後 我們伺服器後端 也必須要去記錄到底
是誰使用這個 cookie ,這組帳號 能不能 從其他地放登入等等,
為什麼要使用 spring boot + redis 去設計,比較可能的原因就是
在每一個 method 的請求 都必須要夾帶 cookie 去判別到底是否維持登入的狀態
類似簽章的功能那我們的系統大致上來模擬一下,比較需要注意的是下面 nginx 我們要做的功能有大致上這些
首先我們要到
- vue axios 開啟每次請求都夾帶cookie
- install redis
- 配置 spring boot
- 編譯 spring boot 成 兩個 port (以提供測試
- 搭配 nginx 使用負載平衡 觀看 key 值是否有不同
- 在 login 的頁面 同一個瀏覽器下 ,是否可以達到 不用 登入帳號密碼直接導向內部畫面
這個 chrome 插件已經用很久了
然後伺服器返回 一個 hash 然後我們的 就可以 照著這個 key 去判斷到底是
不是維持這組帳號 是不是 中斷,然後 我們伺服器後端 也必須要去記錄到底
是誰使用這個 cookie ,這組帳號 能不能 從其他地放登入等等,
為什麼要使用 spring boot + redis 去設計,比較可能的原因就是
在每一個 method 的請求 都必須要夾帶 cookie 去判別到底是否維持登入的狀態
類似簽章的功能那我們的系統大致上來模擬一下,比較需要注意的是下面 nginx 我們要做的功能有大致上這些
首先我們要到
Install redis
apt-get install redis
redis-server
redis-cli
https://qbgbook.gitbooks.io/spring-boot-reference-guide-zh/II. Getting started/11.5. Creating an executable jar.html?q=
mvnw.cmd package
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
<!-- 2.1.5.RELEASE-->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<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>
</dependencies>
<build>
<defaultGoal>compile</defaultGoal>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
</plugins>
</build>
</project>
使用vue anios 模組必須要注意
需要再
axios.defaults.withCredentials=true;//让ajax携带cookie
這樣才能 讓 spring boot 內建 的 redis 共享內存工作
然後 我們也要讓後端 的
這邊 加上
再來 就是配上 nginx 共享內存就完成囉!
mvnw.cmd package
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
<!-- 2.1.5.RELEASE-->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<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>
</dependencies>
<build>
<defaultGoal>compile</defaultGoal>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
</plugins>
</build>
</project>
需要再
axios.defaults.withCredentials=true;//让ajax携带cookie
然後 我們也要讓後端 的
再來 就是配上 nginx 共享內存就完成囉!
由 spring boot 幫我們管理 session
///跨網域
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/httpMethod/**")
.allowCredentials(true)
.allowedOrigins("*");//允许域名访问,如果*,代表所有域名
//.allowedOrigins("http://localhost:9527");//允许域名访问,如果*,代表所有域名
registry.addMapping("/httpMethod2**")
.allowedMethods("GET")
.allowCredentials(true)
.allowedOrigins("http://localhost:8080");//允许域名访问,如果*,代表所有域名
registry.addMapping("/setSession")
.allowCredentials(true)
.allowedOrigins("*");//允许域名访问,如果*,代表所有域名
//.allowedOrigins("http://localhost:9527");//允许域名访问,如果*,代表所有域名
registry.addMapping("/getSession")
.allowCredentials(true)
.allowedMethods("GET")
.allowedOrigins("*");//允许域名访问,如果*,代表所有域名
registry.addMapping("/removeSession")
.allowCredentials(true)
.allowedMethods("GET")
.allowedOrigins("*");//允许域名访问,如果*,代表所有域名
}
};
}
@RequestMapping(value = "/setSession", method = RequestMethod.GET)
@CrossOrigin
public void setSession(HttpServletRequest request, HttpServletResponse response) {
System.out.println(request.getSession().getId().toString());
request.getSession().setAttribute("name", "test");
// request.getSession().setAttribute("name2", "tom2");
}
@RequestMapping(value = "/getSession", method = RequestMethod.GET)
@CrossOrigin
public List getInterestPro(HttpServletRequest request, HttpServletResponse response) throws JsonProcessingException{
System.out.println(request.getSession().getId().toString());
System.out.println(request.getSession().getAttribute("name"));
ObjectMapper objectMapper = new ObjectMapper();
if( request.getSession().getAttribute("name") != null)
listest2.setCode(200);
else
listest2.setCode(404);
//select 所有 redis
Set<byte[]> keys = jedisConnectionFactory().getConnection().keys("*sessions:expires*".getBytes());
Iterator<byte[]> it = keys.iterator();
while(it.hasNext()){
byte[] data = (byte[])it.next();
System.out.println(new String(data, 0, data.length));
}
String userJsonStr = objectMapper.writeValueAsString(listest2);
//System.out.print(userJsonStr);
return listest2;
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConFactory
= new JedisConnectionFactory();
jedisConFactory.setHostName("localhost");
jedisConFactory.setPort(6379);
return jedisConFactory;
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
///跨網域
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/httpMethod/**")
.allowCredentials(true)
.allowedOrigins("*");//允许域名访问,如果*,代表所有域名
//.allowedOrigins("http://localhost:9527");//允许域名访问,如果*,代表所有域名
registry.addMapping("/httpMethod2**")
.allowedMethods("GET")
.allowCredentials(true)
.allowedOrigins("http://localhost:8080");//允许域名访问,如果*,代表所有域名
registry.addMapping("/setSession")
.allowCredentials(true)
.allowedOrigins("*");//允许域名访问,如果*,代表所有域名
//.allowedOrigins("http://localhost:9527");//允许域名访问,如果*,代表所有域名
registry.addMapping("/getSession")
.allowCredentials(true)
.allowedMethods("GET")
.allowedOrigins("*");//允许域名访问,如果*,代表所有域名
registry.addMapping("/removeSession")
.allowCredentials(true)
.allowedMethods("GET")
.allowedOrigins("*");//允许域名访问,如果*,代表所有域名
}
};
}
@RequestMapping(value = "/setSession", method = RequestMethod.GET)
@CrossOrigin
public void setSession(HttpServletRequest request, HttpServletResponse response) {
System.out.println(request.getSession().getId().toString());
request.getSession().setAttribute("name", "test");
// request.getSession().setAttribute("name2", "tom2");
}
@RequestMapping(value = "/getSession", method = RequestMethod.GET)
@CrossOrigin
public List getInterestPro(HttpServletRequest request, HttpServletResponse response) throws JsonProcessingException{
System.out.println(request.getSession().getId().toString());
System.out.println(request.getSession().getAttribute("name"));
ObjectMapper objectMapper = new ObjectMapper();
if( request.getSession().getAttribute("name") != null)
listest2.setCode(200);
else
listest2.setCode(404);
//select 所有 redis
Set<byte[]> keys = jedisConnectionFactory().getConnection().keys("*sessions:expires*".getBytes());
Iterator<byte[]> it = keys.iterator();
while(it.hasNext()){
byte[] data = (byte[])it.next();
System.out.println(new String(data, 0, data.length));
}
String userJsonStr = objectMapper.writeValueAsString(listest2);
//System.out.print(userJsonStr);
return listest2;
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConFactory
= new JedisConnectionFactory();
jedisConFactory.setHostName("localhost");
jedisConFactory.setPort(6379);
return jedisConFactory;
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
進階
這邊比較進階的是除了 在 spring boot 內建的 sesion 可以操作 redis 的話
我們可能要考慮後期配置 ,我們在 加開一個 可以額外操作key 的地方 ,或許
可以達到監控,那我們可以做到 一個 key 只能登入 一台電腦的效果
那麼實際運作的圖就是
//select 所有 redis
Set<byte[]> keys = jedisConnectionFactory().getConnection().keys("*sessions:expires*".getBytes());
Iterator<byte[]> it = keys.iterator();
while(it.hasNext()){
byte[] data = (byte[])it.next();
System.out.println(new String(data, 0, data.length));
}
我們可能要考慮後期配置 ,我們在 加開一個 可以額外操作key 的地方 ,或許
可以達到監控,那我們可以做到 一個 key 只能登入 一台電腦的效果
那麼實際運作的圖就是
//select 所有 redis
Set<byte[]> keys = jedisConnectionFactory().getConnection().keys("*sessions:expires*".getBytes());
Iterator<byte[]> it = keys.iterator();
while(it.hasNext()){
byte[] data = (byte[])it.next();
System.out.println(new String(data, 0, data.length));
}
配置檔案篇
pom.xml檔案已經也丟在 github 上面以提供瀏覽
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
<!-- 2.1.5.RELEASE-->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<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>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
</dependency>
</dependencies>
<build>
<defaultGoal>compile</defaultGoal>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
<!-- 2.1.5.RELEASE-->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<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>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
</dependency>
</dependencies>
<build>
<defaultGoal>compile</defaultGoal>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
</plugins>
</build>
</project>