分散セッション共有の問題
ログインに成功すると、ホームページに移動します。以前は单体应用
、ページ間でデータを転送するためにセッションが一般的に使用されていました。
返されたユーザー情報を認証サービスで HttpSession を使用してOAuth2Controller weibo函数
配信しましたが、ログインに成功した後、モールのホームページがセッションでユーザー情報を取得できないことがわかりました。
各セッションにはスコープがあり、認証サービスは認証サービスのセッション(サーバー内のメモリデータ)しか取得できません、モールのホームページはコモディティサービスなので当然利用できません。
- 異なるドメイン名間でセッションを共有することはできません
- 同じセッション ドメイン名をサービス間で共有することはできません
セッション共有の問題の解決策
春のセッション
基本原則
package com.atlinxi.gulimall.authserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
/**
*
* todo 好几个地方老师的源码和我看的源码是不一样的,先跟着老师的看一遍,以后有需要再自己整理吧
*
* springSession的核心原理
*
* 1. @EnableRedisHttpSession导入@Import({RedisHttpSessionConfiguration.class})配置
* 1.1 给容器中添加了一个组件
* SessionRepository ==> RedisOperationsSessionRepository:redis操作session。session的crud类
* 1.2 SessionRepositoryFilter == > filter:session存储过滤器,每个请求过来都必须经过filter
* 1. 创建的时候,就自动从容器中获取到了SessionRepository:
* 2. 原始的request,response都被包装。SessionRepositoryRequestWrapper,SessionRepositoryResponseWrapper
* 3. 以后获取session。原生的request.getSession()
* 4. 过滤器将request包装成SessionRepositoryRequestWrapper,放行的是SessionRepositoryRequestWrapper
* SessionRepositoryRequestWrapper.getSession(),它是从SessionRepository 中获取到的,也就是从redis中获取到的
* 用的是装饰者模式
*
* springSession所有我们需要考虑的问题,都帮我们做了
*
* 例如:浏览器不关,虽然是30min过期,springSession也会帮我们自动续期
*
*
*/
// 整合redis作为session存储
@EnableRedisHttpSession
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class GulimallAuthServerApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallAuthServerApplication.class, args);
}
}
認証サービス
@EnableRedisHttpSession をスタートアップ クラスに追加します
// 配置文件
spring.application.name=gulimall-auth-server
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
server.port=20000
spring.thymeleaf.cache=false
spring.redis.host=192.168.56.10
spring.redis.port=6379
spring.session.store-type=redis
server.servlet.session.timeout=30m
構成
// 该config所有涉及到session服务的都需要添加
package com.atlinxi.gulimall.authserver.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
@Configuration
public class GulimallSessionConfig {
// 解决分布式session中子域共享的问题
@Bean
public CookieSerializer cookieSerializer(){
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setDomainName("gulimall.com");
cookieSerializer.setCookieName("GULISESSION");
return cookieSerializer;
}
// 如果不配置json序列化的话,默认用的是java序列化
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}
共通定数
package com.atlinxi.common.constant;
public class AuthServerConstant {
public static final String SMS_CODE_CACHE_PREFIX = "sms:code:";
public static final String LOGIN_USER = "loginUser";
}
コントローラ
以前に書いたコードは httpSession を使用してアクセスされていますが、springSession が提供するものはコードを変更する必要はなく、上記の設定のみが必要です。
以前は Weibo ログインをセッションに保存しましたが、ここでは以前の通常のログインも追加します。
@PostMapping("/login")
public String login(UserLoginVo vo, RedirectAttributes redirectAttributes, HttpSession httpSession){
R login = memberFeignService.login(vo);
if (login.getCode()==0){
// 成功放到session中
MemberRespVo data = login.getData("data", new TypeReference<MemberRespVo>() {
});
httpSession.setAttribute(AuthServerConstant.LOGIN_USER,data);
return "redirect:http://gulimall.com";
}else {
Map<String,String> errors = new HashMap<>();
errors.put("msg",login.getData("msg",new TypeReference<String>(){
}));
redirectAttributes.addFlashAttribute("errors",errors);
return "redirect:http://auth.gulimall.com/login.html";
}
}
}
MVN
<?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 https://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.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.atlinxi.gulimall</groupId>
<artifactId>gulimall-auth-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gulimall-auth-server</name>
<description>认证中心(社交登录、OAuth2.0、单点登录)</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.4</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 由于SpringCloud Feign高版本不使用Ribbon而是使用spring-cloud-loadbalancer,
所以需要引用spring-cloud-loadbalancer或者降版本-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!-- 整合springSession解决session共享问题-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.atlinxi.gulimall</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</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 https://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.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.atlinxi.gulimall</groupId>
<artifactId>gulimall-product</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gulimall-product</name>
<description>谷粒商城-商品服务</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.4</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>com.atlinxi.gulimall</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 由于SpringCloud Feign高版本不使用Ribbon而是使用spring-cloud-loadbalancer,
所以需要引用spring-cloud-loadbalancer或者降版本-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!-- 整合springSession解决session共享问题-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 页面渲染我们使用thymeleaf,这应该和freemarker是差不多的,都是模板引擎-->
<!-- 优点:它是一个自然化语言,编写的语言前端可以直接使用,方便前后人员的分工合作-->
<!-- 缺点:性能比其他模板引擎要低一点,但是我们在生产环境开启了它的缓存功能,性能也是很高的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--
spring元数据处理器,加了就有提示了,不加也没任何问题
optional 依赖不会被传递
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- 解决thymeleaf页面修改必须得重启服务器的问题,页面修改之后,需要重新build修改的页面-->
<!-- 前提是需要关闭thymeleaf的缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- 以后使用redisson作为所有分布式锁,分布式对象等功能框架-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
ログイン
以前は、異なるサブドメイン間でセッションを共有できない問題を解決するために分散セッションを使用していました。
システムがマルチシステムの場合、これは適用されません。他のシステムがセッションを共有できないように、サブドメインを最高レベルの gulimall.com にアップグレードすることしかできません。
先生はシングル サインオン用のサーバーとクライアントを自分で書き、その原理を説明しただけで、実際のプロジェクトに適用しなかったので、このセクションを先に進めて、後で話します。
スー・インランさんの両親は非常に早くに離婚し、彼女の母親は彼女のキャリアを重視し、頻繁に出張に出かけ、乳母が彼女の基本的なニーズの世話をしてくれました。周りに仲間はいませんが、必要なときは必ず母がすぐに戻ってきます。母は決して子供をだますような話し方はせず、大人の世界のこともたくさん話してくれました。
校内暴力に対する母親の「闘い」
https://baijiahao.baidu.com/s?id=1760481532554271247