SpringBoot基于token的请求验证

一,SpringBoot实现基于token的登录验证

原理:客户端通过用户名和密码调用登录接口,当验证数据库中存在该用户之后,将用户的信息按照token的生成,生成一个字符串token,返回给客户端,客户端在调用其他接口的时候需要在请求头上带上token,来验证登录信息。

二,样例(基于MybatisPlus)

  • 导入依赖

<dependency>
    <groupId>io.jsonwebtokengroupId>
    <artifactId>jjwtartifactId>
    <version>0.6.0version>
dependency>
  • 编写jwt工具类
@Component
public class JwtUitls {
    /**
     * 过期时间5分钟
     */
    private static final long EXPIRE_TIME=5*60*1000;
    /**
     * 加密密钥
     */
    private static final String KEY = "zhengdonghui";

    /**
     * 生成token
     * @param id    用户id
     * @param userName  用户名
     * @return
     */
    public static String createToken(String id,String userName){
        Map<String,Object> header = new HashMap();
        header.put("typ","JWT");
        header.put("alg","HS256");
        //setID:用户ID
        //setExpiration:token过期时间  当前时间+有效时间
        //setSubject:用户名
        //setIssuedAt:token创建时间
        //signWith:加密方式
        JwtBuilder builder = Jwts.builder().setHeader(header)
                .setId(id)
                .setExpiration(new Date(System.currentTimeMillis()+EXPIRE_TIME))
                .setSubject(userName)
                .setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256,KEY);
        return builder.compact();
    }
	//因为过滤器是在ApplicationContext前面加载的,获取不到IOC容器里面的bean,可以用这种方法获取
    public static  <T> T getBean(Class<T> clazz, HttpServletRequest request){
        WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
        return applicationContext.getBean(clazz);
    }
    /**
     * 验证token是否有效
     * @param token  请求头中携带的token
     * @return  token验证结果  2-token过期;1-token认证通过;0-token认证失败
     */
    public static int verify(String token,HttpServletRequest request){
        AdminMapper adminMapper=getBean(AdminMapper.class,(HttpServletRequest)request);
        Claims claims = null;
        try {
            //token过期后,会抛出ExpiredJwtException 异常,通过这个来判定token过期,1验证成功,0验证失败
            claims = Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody();
        }catch (ExpiredJwtException e){
            return 2;
        }
        //从token中获取用户id,查询该Id的用户是否存在,存在则token验证通过
        Admin admin = adminMapper.selectById(claims.getId());
        if(!Objects.isNull(admin)){
            return 1;
        }
        return 0;
    }

}

  • 编写过滤器
public class AuthFilter implements Filter {

    private JwtUitls jwtUitls=new JwtUitls();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        Map<String,String> map=new HashMap<>();
        String requestURI = ((HttpServletRequest) servletRequest).getRequestURI();
        if(requestURI!=null){
            if(StringUtils.equalsIgnoreCase("/login",requestURI)){
                filterChain.doFilter(servletRequest,servletResponse);
                return;
            }else{
                String token = ((HttpServletRequest) servletRequest).getHeader("token");
                if(StringUtils.isNotBlank(token)){
                    //token验证结果
                    int verify  = JwtUitls.verify(token,(HttpServletRequest) servletRequest);
                    if(verify != 1){
                        //验证失败
                        if(verify == 2){
                            map.put("500","token已过期");
                        }else if(verify == 0){
                            map.put("500","用户信息验证失败");
                        }
                    }else if(verify  == 1){
                        //验证成功,放行
                        filterChain.doFilter(servletRequest,servletResponse);
                        return;
                    }
                }else {
                    map.put("500","未携带token信息");
                }
            }
        }
        servletResponse.setContentType("application/json");
        servletResponse.setCharacterEncoding("utf-8");
        PrintWriter writer = servletResponse.getWriter();
        writer.write(map.toString());
        writer.flush();
        writer.close();

    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<AuthFilter> registAuth(){
        FilterRegistrationBean<AuthFilter> filterFilterRegistrationBean=new FilterRegistrationBean<>();
        filterFilterRegistrationBean.setFilter(new AuthFilter());//添加自己的过滤器
        filterFilterRegistrationBean.setName("token-Auth");
        filterFilterRegistrationBean.addUrlPatterns("/*");//拦截所有请求
        filterFilterRegistrationBean.setOrder(1);//优先执行,数月小,优先级越高
        return filterFilterRegistrationBean;
    }
}
  • controller层测试
@RestController
public class AdminController {

    @Autowired
    private AdminService adminService;

    @Autowired
    private JwtUitls jwtUitls;

    @GetMapping("/login")
    public String getToken(Admin admin){
        Map<String,Object> map=new HashMap<>();
        map.put("user_name",StringUtils.isNotBlank(admin.getUserName())?admin.getUserName():"");
        map.put("password",StringUtils.isNotBlank(admin.getPassword())?admin.getPassword():"");
        List<Admin> admins = adminService.getBaseMapper().selectByMap(map);
        if(admins.size()>0){
            String token = jwtUitls.createToken(String.valueOf(admins.get(0).getUid()), admins.get(0).getUserName());
            return token;
        }
        return null;
    }

    @GetMapping("/selectAll")
    public Object selectAll(){
        List<Admin> admins = adminService.getBaseMapper().selectList(null);
        if(!CollectionUtils.isEmpty(admins)){
            return new Result<List<Admin>>(200,"成功",admins);
        }
        return new Result<List<Admin>>(500,"失败",null);
    }
}

SpringBoot基于token的请求验证_第1张图片
SpringBoot基于token的请求验证_第2张图片
SpringBoot基于token的请求验证_第3张图片

你可能感兴趣的:(java,spring,boot,springmvc)