SpringBoot使用拦截器、Token进行登录拦截

什么是Token?

  • 客户端发送能验证自身信息的数据给服务端
  • 服务端接收数据并且进行加密然后发送给客户端,这个加密的东西就是token
  • 每次客户端发送请求的时候就携带这个token进行验证
  • 具体情况百度

Token工具类

package com.parsley.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 *
 * @Auther: Parsley
 * @Date: 2021/02/02/21:24
 * @Description:
 */
public class TokenUtil {

    //签名的密钥
    public static final String SECRET = "password";
    //签发者
    public static final String ISSUER = "hjj";
    //面向的用户
    public static final String SUBJECT = "user";
    //签发时间
    public static final Integer TTLMILLIS= 360000;


    /**
     * 生成token
     *
     * @param id 一般传入userName
     * @return
     */
    public static String createJwtToken(String id){
        return createJwtToken(id,ISSUER,SUBJECT,TTLMILLIS);
    }

    public static String createJwtToken(String id,String subject){
        return createJwtToken(id,ISSUER,subject,TTLMILLIS);
    }

    /**
     * 生成Token
     *
     * @param id        编号
     * @param issuer    该JWT的签发者,是否使用是可选的
     * @param subject   该JWT所面向的用户,是否使用是可选的;
     * @param ttlMillis 签发时间 (有效时间,过期会报错)
     * @return token String
     */
    public static String createJwtToken(String id, String issuer, String subject, long ttlMillis) {

        //签名算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        //签发当前时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //根据密钥生成密钥
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes,signatureAlgorithm.getJcaName());

        //Token建造器
        JwtBuilder builder = Jwts.builder().setId(id).setIssuedAt(now).setSubject(subject).setIssuer(issuer).signWith(signatureAlgorithm,signingKey);

        //设置过期时间
        if(ttlMillis>=0){
            long expMillis = nowMillis + ttlMillis;
            Date exp =new Date(expMillis);
            builder.setExpiration(exp);
        }

        //压缩
        return builder.compact();
    }


    //解析Token
    public static Claims parseJwt(String jwt){
        Claims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(SECRET)).parseClaimsJws(jwt).getBody();
        return claims;
    }



}

SpringBoot进行登录拦截

自定义注解–无需登录注解

被该注解进行注解的是不需要登陆的拦截器直接放行

package com.parsley.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * [无需登录]
 */

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface NoNeedLogin {
}

拦截器

注意:HandlerInterceptorAdapter已经过时了这里使用实现HandlerInterceptor接口的方式进行实现

package com.parsley.interceptor;

import com.parsley.anno.NoNeedLogin;
import com.parsley.pojo.FangDong;
import com.parsley.pojo.ZuKe;
import com.parsley.service.FangDongService;
import com.parsley.service.LoginService;
import com.parsley.service.ZuKeService;
import com.parsley.utils.TokenUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private FangDongService fangDongService;
    @Autowired
    private ZuKeService zuKeService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //是不是映射到方法上
        boolean isHandlerMethod = handler instanceof HandlerMethod;
        if(!isHandlerMethod){
            System.out.println("不是方法上");
            return true;
        }
        //不需要登录的注解
        boolean isNoNeedLogin= ((HandlerMethod) handler).getMethodAnnotation(NoNeedLogin.class)!=null;
        if(isNoNeedLogin){
            System.out.println("无需登录");
            return true;
        }
        //需要登录验证
        String token = request.getHeader("Authorization");

        if(null == token){
            System.out.println("无token");
        }else {
            Claims claims = null;
            try{
                claims = TokenUtil.parseJwt(token);
            }catch (Exception e){
                System.out.println("token有误");
            }
            if (null != claims){
//                Integer id = Integer.valueOf(claims.getId());
//                String subject=claims.getSubject();
//                if(subject.equals(LoginService.TYPE_ZU_KE)){
//                    ZuKe zuKe = zuKeService.getById(id);
//                    if(zuKe!=null){
//                        request.setAttribute(LoginService.TYPE_ZU_KE,zuKe);
//                        return true;
//                    }
//                }else if (subject.equals(LoginService.TYPE_FANG_DONG)){
//                    FangDong fangDong =fangDongService.getById(id);
//                    if (fangDong!=null){
//                        request.setAttribute(LoginService.TYPE_FANG_DONG,fangDong);
//                        return true;
//                    }
//                }
//                return false;
            }
        }
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

对SpringMvc进行扩展配置拦截器

注意:不要添加@EnableWebMvc注解,该注解会导致MVC自动配置失效

package com.parsley.config;

import com.parsley.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Created with IntelliJ IDEA.
 *
 * @Auther: Parsley
 * @Date: 2021/02/07/20:08
 * @Description:
 */
@Configuration
public class MyWebAppConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
    }
}

Maven

		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt</artifactId>
			<version>0.9.1</version>
		</dependency>
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
前端与Spring Boot拦截器进行Token校验的基本思路是:前端将用户登录时获取到的Token放在请求的HeaderSpring Boot拦截器通过拦截请求获取HeaderToken,然后根据Token进行校验。 下面是具体的步骤: 1. 前端在用户登录成功后,将Token保存在浏览器的本地存储(localStorage或sessionStorage),并在每次请求时将Token放在请求的Header。例如: ``` axios.defaults.headers.common['Authorization'] = 'Bearer ' + token; ``` 2. Spring Boot拦截器通过实现HandlerInterceptor接口来拦截请求,并在拦截器获取HeaderToken。例如: ``` public class TokenInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("Authorization"); // 根据Token进行校验 if (token == null || !token.startsWith("Bearer ")) { response.setStatus(HttpStatus.UNAUTHORIZED.value()); return false; } // ... return true; } // ... } ``` 3. 在Spring Boot的配置类配置拦截器,使其生效。例如: ``` @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired private TokenInterceptor tokenInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(tokenInterceptor) .addPathPatterns("/**") .excludePathPatterns("/login"); } // ... } ``` 在上面的代码,我们将TokenInterceptor添加到拦截器,并设置了拦截所有请求(除了/login)。 这样,当前端发送请求时,拦截器拦截请求并获取HeaderToken,然后进行校验,如果校验不通过则返回401状态码,否则继续执行请求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值