Spring boot 集成JWT实现token验证

1、引入依赖


    com.auth0
    java-jwt
    3.4.0

2、自定义注解

跳过验证注解

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

/**
 * @email [email protected]
 * @author:菜园子
 * @date: 2019/6/11
 * @time: 10:58
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
    boolean required() default true;
}

验证token权限注解

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

/**
 * @email [email protected]
 * @author:菜园子
 * @date: 2019/6/11
 * @time: 11:04
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
    boolean required() default true;
}

3、工具类(jwt.key配置文件application.properties)

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.diveyun.gas.entity.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @email [email protected]
 * @author:菜园子
 * @date: 2019/6/13
 * @time: 14:06
 */
@Component
public class JwtUtils {

    private static String key;

    @Value("${jwt.key}")
    public void setKey(String key) {
        JwtUtils.key = key;
    }

    /*创建token*/
    public static String getToken(User user){
        String token = JWT.create().withAudience(String.valueOf(user.getId()))
                .sign(Algorithm.HMAC256(key));
        return token;
    }

    /*校验token*/
    public static void verify(String token,User user){
        // 验证 token
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(key)).build();
        jwtVerifier.verify(token);
    }
}

4、拦截器

import com.auth0.jwt.JWT;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.diveyun.gas.anno.PassToken;
import com.diveyun.gas.anno.UserLoginToken;
import com.diveyun.gas.dao.UserDao;
import com.diveyun.gas.entity.User;
import com.diveyun.gas.tools.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
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;
import java.lang.reflect.Method;

/**
 * @email [email protected]
 * @author:菜园子
 * @date: 2019/6/11
 * @time: 14:53
 */
public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired
    private UserDao userDao;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
        String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token
        // 如果不是映射到方法直接通过
        if(!(object instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod=(HandlerMethod)object;
        Method method=handlerMethod.getMethod();
        //检查是否有passtoken注释,有则跳过认证
        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }
        //检查有没有需要用户权限的注解
        if (method.isAnnotationPresent(UserLoginToken.class)) {
            UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
            if (userLoginToken.required()) {
                // 执行认证
                if (token == null) {
                    throw new RuntimeException("无token,请重新登录");
                }
                // 获取 token 中的 user id
                Integer userId;
                try {
                    userId = Integer.parseInt(JWT.decode(token).getAudience().get(0));
                } catch (JWTDecodeException j) {
                    throw new RuntimeException("401");
                }
                User user = userDao.findById(userId);
                if (user == null) {
                    throw new RuntimeException("用户不存在,请重新登录");
                }
                // 验证 token
                try {
                    JwtUtils.verify(token,user);
                } catch (JWTVerificationException e) {
                    throw new RuntimeException("token异常,请重新登录!");
                }
                return true;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest,
                           HttpServletResponse httpServletResponse,
                           Object o, ModelAndView modelAndView) throws Exception {

    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest,
                                HttpServletResponse httpServletResponse,
                                Object o, Exception e) throws Exception {
    }
}

5、配置拦截器

import com.diveyun.gas.interceptor.AuthenticationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @email [email protected]
 * @author:菜园子
 * @date: 2019/6/11
 * @time: 16:21
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**");
    }
    @Bean
    public AuthenticationInterceptor authenticationInterceptor() {
        return new AuthenticationInterceptor();
    }
}

6、测试

@RequestMapping("/login")
@WebLog(description = "访问登录接口")
@PassToken
public ReturnJson login(User user){
    ReturnJson result = new ReturnJson();
    try {
        if (StringUtils.isEmpty(user.getUserName()) || StringUtils.isEmpty(user.getPassword())){
            result.setMsg("用户名或密码不能为空!");
            return  result;
        }
        JSONObject data = new JSONObject();
        List list = userDao.findAll(user);
        if (list.size() != 1){
            result.setMsg("用户名不存在!");
            return result;
        }
        User dbUser = list.get(0);
        if (!StringUtils.equals(user.getPassword(),dbUser.getPassword())){
            result.setMsg("密码不正确!");
            return result;
        }
        String token = JwtUtils.getToken(dbUser);
        data.put("userName",user.getUserName());
        data.put("token",token);
        result.setCode(0);
        result.setMsg("请求成功!");
        result.setData(data.toString());
    }catch (Exception e){
        throw new RuntimeException(e.getMessage());
    }
    return result;
}

你可能感兴趣的:(JWT)