0%

(五)谷粒商城开发-认证服务开发

1. 用户注册

1.1 发送验证码

  • 使用 Redis 缓存存储指定生存时间验证码,其中手机号为 key,值的时间戳 + 验证码。时间戳的作用用于实现用户执行时间内不能重复发送验证码;
  • 验证码的发送采阿里云第三方服务实现,传入指定手机号和验证码;
  • 缓存中的验证码未过期且与用户的验证码相互匹配,且此时支持再次发送验证码,那么再次调用第三方服务发送验证码;
  • 缓存中的验证码已经过期,那么生成新的验证码并调用第三方服务发送验证码。

1.2 用户密码加密

为了保证用户的数据安全,用户的密码需要以密文的方式存储到数据库中,如下是几种加密策略:

1.2.1 MD5 加密

可以使用 MD5 工具类实现密码进行加密,虽然 MD5 加密是不可逆的,但是可能会被暴力破解

1.2.2 MD5 盐值加密

在 MD5 加密的基础上,可以生成一段随机的盐值(随机序列)并按照自定义拼接规则(避免通过盐值反向破解)与对密码进行拼接,不过这个盐值需要存储到数据库中。此方法虽然可以避免密码被破解,但是需要向数据库存储盐值。

1.2.3 BCrypt 加密

spring security 提供了一个加密工具,可以实现比 MD5 盐值加密更便捷和优异的加密结果,代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
//1. 密码加密逻辑
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encode = passwordEncoder.encode("这是密码");
// 密码入库...

// 2. 密码匹配逻辑
String password = "这是密码"; // 用户输入的密码
String passwordDb = "asdhashdashd"; // 从数据库获取的密码密文
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
boolean matches = passwordEncoder.matches(password, passwordDb);
if (matches) {
// 为 true 则密码匹配成功
}

2. 分布式 Session 共享和 SpringSession 原理

2.1 Session 共享问题

在单服务应用下,用户使用浏览器登录成功后,后台会生成一个指定 sessioId 的 Cookie 并命令浏览器保存起来。用户下次进行访问网站时就可以带上该 Cookie 进行用户验证通过时就可以免登录操作。

单服务 session 获取

但是单服务应用下,不能跨子域名和多服务共享 session。如下图,比如存在多个会员服务,因为存在第一个会员服务存在 session 而第二个会员服务不存在 session,那么就存在服务之间的共享问题。而对于不同的服务则存在跨域名 session 共享问题,比如用户使用会员服务登录成功后获取到 session,但是订单服务则无法获取。

单服务 session 共享问题

2.2 Session 共享问题解决策略

1)Session 复制同步方案:比如不同 tomcat 之间进行 session 复制同步共享

Session 复制同步方案

2)客户端以 Cookie 形式存储 session

客户端存储

3)Hash 一致性:将不同的 IP 以 hash 形式映射到多台服务器上,由指定服务器存储对应 session 信息

Hash 一致性

4)统一 session 存储

统一存储

5)跨域名-子域 session 共享问题

前面已经说过,普通的 session 机制对于不同子域名之间的 session 共享是不起作用的,即不同域名之间无法进行 session 共享。但是我们可以设置 session 的作用域,即扩大其作用域到父域名上,这样不同的子域就可以实现 session 共享。

子域 session 共享问题

2.3 SpringSession 原理

SpringSession 是 Spring 提供的一个分布式 session 共享框架,其可以采用公共的存储容器(MongoDB、Redis)来存储多个服务的 Session 信息,并支持设置 Session 的作用域,其可以简单的解决 Session 共享问题。

如下是 SpringSession 的核心代码,其重点就是 SpringSession 对原有的 Session 对应进行了重新和包装(装饰者模式),后面我们在登录成功后往前端生成返回 Cookie 时的 Sesssion 对象就是 SpringSession 包装后的。

SpringSession 核心代码

3. 用户登录

3.1 OAuth2 社交账号登录

社交登录流程如下所示:

社交登录流程

3.2 单点登录

下图是存在认证中心的分布式单点登录流程:

单点登录

------ 本文结束------