持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第32天,点击查看活动详情
拦截器 + token的登录验证
相信各位有进行过系统开发经验的朋友们,肯定会了解一个系统最基础的功能,那就是实现用户登录,而这个用户登录是需要经过认证的,只要通过了认证才会让用户访问其他重要页面的,就好像在某个系统中,你不登录和登录所能执行的操作是不一样的。
今天我们就一起来聊聊这个话题,话不多说,我们马上出发!
基于jwt的token认证
token就相当于一个令牌一样,用户第一次登录的时候,后端系统需要生成一个独一无二的token返回给前端,以后的每次访问前端都会自动带上这个token,这样就区分开了,登录状态和未登录状态。
一般未登录状态在访问时,系统会自动重定向到登录页面,给用户登录。
下面给出一种生成token的实现方式:
//生成token字符串
public static String createToken(Long userId, String userName, String email) {
String token = Jwts.builder()
.setSubject("YYGH-USER")
.setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
.claim("id", userId)
.claim("email", email)
.claim("userName", userName)
.signWith(SignatureAlgorithm.HS512, tokenSignKey)
.compressWith(CompressionCodecs.GZIP)
.compact();
return token;
}
这个token是根据用户id、用户名、用户邮箱的基本信息来生成的,保证了token和用户的一一对应。
拦截器-拦截请求
下面给出一种拦截器的实现,是通过重写 HandlerInterceptor 中的 preHandle方法来实现的。
具体流程如下:
- 判断到来的请求是否携带了 token,如果没携带,则响应信息并拦截
- 如果到来的请求携带了 token,则在redis中查是否存在对应的token,如果存在,则放行,否则拦截
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
String token = request.getHeader("token");
if (StringUtils.isEmpty(token)) {
response.getWriter().print("用户未登录,快去登录吧,快去!");
return false;
}
Object loginStatus = redisTemplate.opsForValue().get(token);
System.out.println("拦截器,去查redis啦。。。");
if( Objects.isNull(loginStatus)){
response.getWriter().print("token错误,快去检查!");
return false;
}
return true;
}
而上面这个拦截器究竟是拦截什么请求呢?
是所有请求都拦截吗?还是可以设置的呢?
其实是可以设置的。
拦截器的路径配置:
拦截器的配置是通过重写WebMvcConfigurer 中的方法来实现的,下面给出了一个重写addIntercepter方法的实现。
/**
* 拦截
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
String[] addPathPatterns ={
//输入要拦截路径
//拦截所有路径 ,之后再决定放行
"/**"
};
//设置排除放行路径
//要排除路径,排除的路径可以直接放行
String[] excludePathPatterns={
"/system/login", //排除掉登录请求
};
registry.addInterceptor(initAuthInterceptor())
.addPathPatterns(addPathPatterns)
.excludePathPatterns(excludePathPatterns);
}