![](https://i-blog.csdnimg.cn/blog_migrate/2f839c30b2b624e3ffa4ae18bddf1deb.png)
登录
①自定义登录接口
调用ProviderManager的方法进行认证 如果认证通过生成jwt
把用户信息存入redis中
②自定义UserDetailsService
在这个实现类中去查询数据库
校验:
①定义Jwt认证过滤器
获取token
解析token获取其中的userid
从redis中获取用户信息
存入SecurityContextHolder
我们需要做的是:
创建一个实现类,重写方法,实现我们从数据库中根据用户名查询用户信息的功能,
新建类并把用户信息封装在这个类中,然后定义登录接口,并放行这个接口,因为这个页面是在登录之前就能访问的。
//根据用户名查询用户信息
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getUserName,username);
User user = userMapper.selectOne(wrapper);
springsecurity中实现认证功能的是AuthenticationManager的authenticate方法,认证成功后生成一个jwt,里面包含用户信息,我们通过redis定义id为key,jwt为value,同时里面包含了token。
//认证实现
Authentication authenticate = authenticationManager.
authenticate(authenticationToken);
//生成jwt
String jwt = JwtUtil.createJWT(userId);
之后我们还要定义一个过滤器,去获取请求头token,用其中的userid获取登录用户对象,把对象存入springsecurity中的SecurityContextHolder。
//获取token
String token = request.getHeader("token");
//存入SecurityContextHolder
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(loginUser,null,null);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
退出登录时,定义一个接口,删除redis中的认证信息即可。
public ResponseResult logout() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
Long userid = loginUser.getUser().getId();
redisCache.deleteObject("login:"+userid);
return new ResponseResult(200,"退出成功");
}
}