基于springboot使用reids和token实现后端拦截

基于springboot使用reids和token实现后端拦截

场景:最近开发一个简单项目,实现了一些后台的接口,为了服务器和资源的安全,进行拦截。由于此项目的角色只有一个超级管理员,所以也未进行基于角色拦截或基于资源拦截。

说明:前后端使用token作为用户是否登录的标志,前端调用接口时将token放入请求头,后端获取请求头的token验证是否用户登录,从而放行,本质上是根据设置响应对象的是否授权的状态。401 Unauthorized 无权限访问。

逻辑:后端放行登录接口,前端通过登录接口进行登录,登录验证成功后返回一个token信息给前端并以token为键存入redis,前端接受token并缓存,前端访问需要权限的接口时请求头上带上token,后端在redis中获取以token键的值,判断是否为空,从而验证是否登录而是否放行访问接口。

依赖


<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-redisartifactId>
dependency>

拦截器

package xxx.interceptor;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Resource
    private RedisTemplate redisTemplate;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // OPTIONS请求不做校验,
        // 前后端分离的架构, 前端会发一个OPTIONS请求先做预检, 对预检请求不做校验
        if(request.getMethod().toUpperCase().equals("OPTIONS")){
            return true;
        }
        //获取header的token参数
        String token = request.getHeader("token");
        if (token == null || token.isEmpty()) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        }
        Object object = redisTemplate.opsForValue().get(token);
        if (object == null) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        } else {
            return true;
        }
    }
}

实现WebMvcConfigurer,在此配置拦截路径和放行路径

package xxx.config;

import com.homyit.calling.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {

    @Resource
    LoginInterceptor loginInterceptor;

    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(
                         "/user/login"                    
                );
    }
}

登录接口

这里就不详细写了,与拦截无多大关系,当用户登录成功时,以token为键,随便存入任意信息即可。

前端对接

前端可使用axios.interceptors.request.use,在请求头中添加token信息。为了用户可刷新,不丢失token信息,可以使用HTML5封装的sessionStoragec储存token.

你可能感兴趣的