1.社交登录
2.微博社交登录 第三方登录
1.登录微博
2.点击网站接入
3.填写完信息,到这里,写入成功回调 和 失败回调
是重定向,所以可以写本地的地址
3.认证 分布式Session spring-session
域名不一样 发的 jSessionId 就不同,根据域名区分服务器的,一个服务器创建一个 cookie存jSessionId
分布式Session原理,使用子域名,的时候放入父域名的 JsessionId 然后将这个ID 的所存的内容放入Redis ,这样实现不同域名共享同一sessionID.
4.SpringSession
1.导入依赖
老版本需要导入下面两个依赖要不然报错
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
2.yml配置
server:
port: 20000
servlet:
session:
timeout: 30m #30分钟 SESSION过期时间
#配置数据源
spring:
session:
store-type: redis
application:
name: gulimall-auth-server #服务名称
cloud:
nacos:
discovery:
server-addr: 192.168.2.36:8848 #nacos注册中心的地址
thymeleaf:
cache: false
redis:
host: 192.168.232.209
port: 6379
database: 0
3.开启自动配置
@EnableRedisHttpSession//整合 redis 作为 session存储
package com.jmj.gulimall.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
@Controller
public class IndexController {
@GetMapping("/loginUser")
@ResponseBody
public String loginUser(HttpSession httpSession){
httpSession.setAttribute("loginUser",new User("123","jmj"));
return "登录成功";
}
}
package com.jmj.gulimall.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.data.redis.config.annotation.web.http.EnableRedisHttpSession;
@Configuration(proxyBeanMethods = false)
@EnableRedisHttpSession//整合 redis 作为 session存储
public class Config {
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}
Controller
package com.jmj.gulimall.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
@Controller
public class IndexController {
@GetMapping("/loginUser")
@ResponseBody
public String loginUser(HttpSession httpSession){
httpSession.setAttribute("loginUser",new User("123","jmj"));
return "登录成功";
}
@GetMapping("/getSession")
@ResponseBody
public User getSession(HttpSession httpSession){
User loginUser = (User) httpSession.getAttribute("loginUser");
return loginUser;
}
}
4. 2.6.7 springboot 版本之后只用配置配置文件就可以了
5.还存在一点问题
1.默认发的令牌, session= dsajkdjl 作用域:当前域(子域Session共享问题)
2.使用JSON的序列化方式来序列化对象数据到redis中
package com.jmj.gulimall.config;
import com.fasterxml.jackson.databind.ObjectMapper;
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.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
@Configuration(proxyBeanMethods = false)
@EnableRedisHttpSession//整合 redis 作为 session存储
public class Config {
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer(ObjectMapper objectMapper) {
return new GenericJackson2JsonRedisSerializer(objectMapper);//使用不带包名的JSON序列化
}
@Bean
public CookieSerializer cookieSerializer(){
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setCookieMaxAge(60);//单位 : 秒
cookieSerializer.setDomainName("jmjStudy.com");//设置子域名
cookieSerializer.setCookieName("JMJSession");//session名字
return cookieSerializer;
}
}
package com.jmj.gulimall.controller;
import cn.hutool.core.bean.BeanUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
@Controller
public class IndexController {
@GetMapping("/loginUser")
@ResponseBody
public String loginUser(String name,HttpSession httpSession){
httpSession.setAttribute("loginUser",new User("123",name));
return "登录成功";
}
@GetMapping("/getSession")
@ResponseBody
public User getSession(HttpSession httpSession){
Object loginUser = httpSession.getAttribute("loginUser");
User user = BeanUtil.copyProperties(loginUser, User.class);
return user;
}
@GetMapping("/user")
@ResponseBody
public com.jmj.gulimall.config.User getserSession(HttpSession httpSession){
Object loginUser = httpSession.getAttribute("loginUser");
com.jmj.gulimall.config.User user = BeanUtil.copyProperties(loginUser, com.jmj.gulimall.config.User.class);
return user;
}
}
所有服务存取Session 都在Redis 用的SessionId都是同一个,这样就可以达到所有服务都可以共享域 的SessonId 解决了分布式Session的问题。
6.SpringSession原理
一句话精辟解释: 在过滤器放行的时候,偷偷的把原生的 request 和 response 对象换成了它的实现,也就是 调用getSession 的时候拿到的 其实是对redis 操作的Session。但其他的操作还是使用原生的,只不过重写的方法,调用的是子类的,也就是往 redis 里放入 Session,把原生的操作给替换了!
在细节讲一下 : cookie 过期时间 和 Session过期时间不是一个东西
cookie是存储在浏览器客户端的
session是存放在服务器的 ,
cookie过期了 浏览器拿不到 jsessionId 也就拿不到数据
session过期了 更拿不到,因为存储都没有了
然后浏览器执行请求, 对session进行操作的时候 会对session进行续期
但是cookie不会续期,cookie过期了浏览器就不会带着cookie来访问服务器了,再次访问,服务器将会颁发一个新的cookie
完美!!!