认证服务-社交登录/分布式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();
    }
}

 

 

阅读剩余
THE END