基于SpringSecurity,使用JWT设计的登录注册流程
用户注册流程
一般应用提供的主流注册方式是手机号+验证码,用户操作流程如下:
- 1.用户提供手机号,系统发送验证码进行验证
- 2.验证成功,用户填写用户名密码等信息进行注册
SpringSecurity设置
由于SpringSecurity会将所有接口进行拦截鉴权,所以需要将注册流程所需的接口进行开放
开放如下接口:
- POST /sys/sms/send:手机号校验码发送
- PUT /sys/sms/validate:校验码验证
- POST /user:用户注册
系统流程
key
验证成功的key作为一个密钥存储在redis中,用来验证是哪个用户的注册信息,是手机号加密后的字符串
if (registerValidate(telphoneInRequest, codeInRequest)) {
smsKey = passwordEncoder.encode(telphoneInRequest);
logger.info("密钥:" + smsKey);
redisService.set("sms_key_"+ telphoneInRequest, smsKey, new Long(30*60));
}
return CommonReturnType.create(smsKey);
用户登录流程
传统使用SpringSecurity做登录需要实现UserDetailsService接口的loadUserByUsername方法
@Component
public class MyUserDetailsService implements UserDetailsService {
@Autowired
UserMapper userMapper;
@Autowired
PasswordMapper passwordMapper;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
// 根据用户名 s 从数据库查找用户封装UserDetails并返回
// SpringSecurity框架会进行密码校验,然后根据配置的处理器进行登录成功或者失败的处理
}
}
SpringSecurity提供的这种模式因为只提供了用户名s,所以只能支持用户名密码or邮箱密码的这种登录方式,无法实现用户名密码+邮箱密码+手机号验证码三种共存的登录方式
扩展框架实现三种登录方式共存
大致思路是:在已经实现了两种基础的登录方式之后,仿照SpringSecurity提供的UsernamePasswordAuthenticationFilter实现一套TelValidateCodeAuthenticationFilter,并提供TelUserDetailService接口
结构如下:
TelValidateCodeAuthenticationFilter
和框架提供的UsernamePasswordAuthenticationFilter类似,加入到SpringSecurity的过滤器链中,从url上获取参数
创建未验证的token,通过Manager调用Provider进行验证
token的验证过程会通过编写的TelUserDetailService接口访问到其实现,进行验证码校验
TelValidateCodeAuthenticationToken
验证过程中的一个封装类(图中去掉了不重要的类,因为太长了),类似的还有RememberMeAuthenticationToken(记住我),OAuth2Authentication(第三方登录)
JWT校验
Json Web Token,用户在每次无状态请求中标识用户身份
创建
应该创建于登录成功
更新
按照一定规则自动更新,该项目token过期时间设置为10天
提供一个接口,当token过期时间小于5天时进行更新
// 剩余时间
long times = bearer.getExpiration().getTime()-new Date().getTime();
// 过期时间的一半
long halfTime = feheadProperties.getSecurityProperties().getJwtExpiredTime() / 2;
if(times<halfTime){ // 不足一般的时间
// 重新生成token
}
更新规则使项目情况变动较大
校验
编写过滤器JWTAuthenticationFilter进行校验
- 1.从请求头中获取token字符串
- 2.解析出用户信息,若token过期则解析过程便会报错
以上便是在SpringSecurity框架下,登录注册流程以及JWT校验的总结