认证服务-社交登录/分布式session
社交登录
账号密码完成登录
拿到前端传来的用户名或手机号 / 密码
远程调用product-member中方法
MemberServiceImpl中的login方法,对传来的信息,与数据库中的进行对比
@Override
public MemberEntity login(MemberLoginVo vo) {
String loginacct = vo.getLoginacct();
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
// 去数据库查询
MemberEntity entity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("username", loginacct).or().eq("mobile", loginacct));
if(entity == null){
// 登录失败
return null;
}else{
// 前面传一个明文密码 后面传一个编码后的密码
boolean matches = bCryptPasswordEncoder.matches(vo.getPassword(), entity.getPassword());
if (matches){
entity.setPassword(null);
return entity;
}else {
return null;
}
}
}
gitee完成登录
OAuth2.0
gitee登录
gitee OAth 文档: https://gitee.com/api/v5/oauth_doc#/list-item-2
前端页面点击微博登录跳转此链接,修改ID和回调地址
https://gitee.com/oauth/authorize?client_id=应用的ID&redirect_uri=回调地址&response_type=code
gitee回调
上面的链接用户授权后会跳转到:http://回调地址code=abc&
有了code 获取access_token 方法: com.tinstu.gulimallauthserver.controller.OAuth2Controller
https://gitee.com/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}
根据此链接拼接上code ID和key等信息获取access_token
根据access_token获取用户的相关信息:com.tinstu.gulimall.member.service.impl.MemberServiceImpl
此处还有判断用户是不是第一次登录,如果不是 就根据用户的gitee信息注册一个
分布式session
session原理
session存储在服务端,jsessionId存在客户端,每次通过jsessionid
取出保存的数据
问题:但是正常情况下session
不可跨域,它有自己的作用范围
分布式session解决方案
session要能在不同服务和同服务的集群的共享
1) session复制
用户登录后得到session后,服务把session也复制到别的机器上,显然这种处理很不好
2) hash一致性
根据用户,到指定的机器上登录。但是远程调用还是不好解决
3) redis统一存储
最终的选择方案,把session放到redis中
SpringSession整合redis
https://spring.io/projects/spring-session-data-redis
https://docs.spring.io/spring-session/docs/2.4.2/reference/html5/#modules
通过SpringSession
修改session
的作用域
会员服务、订单服务、商品服务,都是去redis里存储session
环境搭建:
Oauth导入依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
修改配置
spring.session.store-type=redis
server.servlet.session.timeout=30m
spring.redis.host=192.168.56.10
启动类添加注解
@EnableRedisHttpSession //创建了一个springSessionRepositoryFilter ,负责将原生HttpSession 替换为Spring Session的实现
public class GulimallAuthServerApplication {
通过以上配置之后,保存到session中的内容将自动同步到Redis
序列化问题:MemberRespVo implements Serializable
自定义springsession完成子域session共享
- 由于默认使用jdk进行序列化,通过导入
RedisSerializer
修改为json序列化 - 并且通过修改
CookieSerializer
扩大session
的作用域至**.gulimall.com
在product和auth中加一个配置类,内容相同
@Configuration
public class MallSessionConfig {
@Bean
public CookieSerializer cookieSerializer(){
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
// 明确的指定Cookie的作用域
cookieSerializer.setDomainName("mall.com");
cookieSerializer.setCookieName(AuthServerCostant.SESSION);
return cookieSerializer;
}
/**
* 自定义序列化机制
* 这里方法名必须是:springSessionDefaultRedisSerializer
*/
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer(){
return new GenericJackson2JsonRedisSerializer();
}
}