java使用jwt实现移动端api接口token认证

首先在pom文件中添加:

   <!--jwt-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.6.0</version>
        </dependency>

创建jwt工具类:


/**
 * jwt工具类
 *
 * @author tuc
 */
@Component("jwtUtil")
public class JwtUtil {

    /**
     * 加密秘钥
     */
    private String secret = "a1g2y47dg3dj59fjhhsd7cnewy73j";

    /**
     * 生成token
     *
     * @param user
     * @return String
     */
    public String generateToken(String user) {
        Map<String, Object> claims = new HashMap<>(1);
        claims.put("sub", user);
        return generateToken(claims);
    }

    /**
     * 生成token
     *
     * @param claims
     * @return String
     */
    private String generateToken(Map<String, Object> claims) {
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(this.generateExpirationDate())
                .setIssuedAt(this.generateCurrentDate())
                .signWith(SignatureAlgorithm.HS512, this.secret)
                .compact();
    }

    private Date generateCurrentDate() {
        return new Date(System.currentTimeMillis());
    }


    private Date generateExpirationDate() {
        /**
         * 有效时间(当前设置30天)
         */
        long expiration = (long) 30 * 24 * 60 * 60 * 1000;
        return new Date(System.currentTimeMillis() + expiration);
    }

    /**
     * 判断token是否可以刷新
     *
     * @param token
     * @param lastPasswordReset
     * @return Boolean
     */
    public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(this.secret)
                    .parseClaimsJws(token)
                    .getBody();
            final Date iat = claims.getIssuedAt();
            final Date exp = claims.getExpiration();
            if (iat.before(lastPasswordReset) || exp.before(generateCurrentDate())) {
                return false;
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 刷新token
     *
     * @param token
     * @return String
     */
    public String refreshToken(String token) {
        String refreshedToken;
        try {
            final Claims claims = Jwts.parser()
                    .setSigningKey(this.secret)
                    .parseClaimsJws(token)
                    .getBody();
            refreshedToken = this.generateToken(claims);
        } catch (Exception e) {
            refreshedToken = null;
        }
        return refreshedToken;
    }

    /**
     * 校验token
     *
     * @param token
     * @return TokenStatus
     */
    public TokenStatus verifyToken(String token) {
        TokenStatus result;
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(this.secret)
                    .parseClaimsJws(token)
                    .getBody();
            final Date exp = claims.getExpiration();
            if (exp.before(generateCurrentDate())) {
                result = TokenStatus.EXPIRED;
            } else {
                result = TokenStatus.VALID;
            }
        } catch (Exception e) {
            result = TokenStatus.INVALID;
        }
        return result;
    }

    /**
     * 获取用户编号
     *
     * @param token
     * @return Integer
     */
    public String getUserNameFromToken(String token) {
        String userName;
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(this.secret)
                    .parseClaimsJws(token)
                    .getBody();
            userName = claims.getSubject();
        } catch (Exception e) {
            userName = null;
        }
        return userName;
    }
}

token状态枚举类:

/**
 * token状态
 *
 * @author tuc
 */
public enum TokenStatus {
    /**
     * 过期的
     */
    EXPIRED("EXPIRED"),
    /**
     * 无效的
     */
    INVALID("INVALID"),
    /**
     * 有效的
     */
    VALID("VALID");

    private final String status;

    TokenStatus(String status) {
        this.status = status;
    }

    public String value() {
        return this.status;
    }
}

创建jwt过滤器:


/**
 * jwt过滤器
 *
 * @author tuc
 */
@Component
public class JwtFilter implements Filter {

    /**
     * 排除拦截的请求
     */
    private String[] excludedPages = {"/login"};

    private static Logger logger = LoggerFactory.getLogger(JwtFilter.class);
    private JwtUtil jwtUtil = new JwtUtil();

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        try {
            for (String page : excludedPages) {
                if (httpRequest.getRequestURI().equals(page)) {
                    chain.doFilter(httpRequest, httpResponse);
                    return;
                }
            }
            String token = httpRequest.getHeader(Constants.TOKEN_HEADER);
            TokenStatus tokenStatus = jwtUtil.verifyToken(token);
            switch (tokenStatus) {
                //有效
                case VALID:
                    String user = jwtUtil.getUserNameFromToken(token);
                    httpRequest.setAttribute(Constants.LOGIN_USER, user);
                    chain.doFilter(httpRequest, httpResponse);
                    break;
                //无效
                case INVALID:
                    accessDeny(httpResponse, 1);
                    break;
                //过期
                case EXPIRED:
                    accessDeny(httpResponse, 2);
                    break;
                default:
                    accessDeny(httpResponse, 1);
                    break;
            }
        } catch (Exception e) {
            logger.error("jwtFilter Exception: {}", e.getMessage());
            accessDeny(httpResponse, 1);
        }
    }


    /**
     * token 校验失败提示
     *
     * @param type 1无效,2过期
     */
    private void accessDeny(HttpServletResponse response, int type) {
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        try {
            writer = response.getWriter();
            ResultModel resultModel = new ResultModel();
            if (1 == type) {
                resultModel = ResultTools.result(1001, "", null);
            } else if (2 == type) {
                resultModel = ResultTools.result(1002, "", null);
            }
            JSONObject jsonObject = new JSONObject(resultModel);
            writer.print(jsonObject);
        } catch (IOException e) {
            System.out.print(e.getMessage());
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

    @Override
    public void init(FilterConfig filterConfig) {
        logger.info("jwtFilter init ...");
    }

    @Override
    public void destroy() {
        logger.info("jwtFilter destroy ...");
    }
}

配置过滤规则:

/**
 * 配置类
 *
 * @author tuc
 */
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {


    @Bean
    public FilterRegistrationBean jwtFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new JwtFilter());
        registration.setName("JwtFilter");
        registration.addUrlPatterns("/*");
        registration.setOrder(1);
        return registration;
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE", "PATCH")
                .allowedHeaders("Origin", "X-Requested-With", "Content-Type", "Accept", "x-auth-token")
                .allowCredentials(false).maxAge(3600);
    }

}

到这里基本已配置完成,下面为使用示例:

创建TestController:


/**
 * 测试Controller
 *
 * @author tuc
 */
@RestController
public class TestController {


    @Autowired
    private JwtUtil jwtUtil;

    /***
     * 测试登录
     * 这里使用用户id来生成token
     */
    @PostMapping("/login")
    public ResultModel login(Integer userId) {
        try {
            Map<String, Object> map = new HashMap<>(1);
            map.put("token", jwtUtil.generateToken(userId + ""));
            return ResultTools.result(0, "", map);
        } catch (Exception e) {
            return ResultTools.result(404, e.getMessage(), null);
        }
    }

    /***
     * 测试jwt验证
     */
    @GetMapping("/api/test")
    public ResultModel getTest(HttpServletRequest request) {
        try {
            String user = request.getAttribute(Constants.LOGIN_USER).toString();
            Map<String, Object> map = new HashMap<>(1);
            map.put("user", user);
            return ResultTools.result(0, "", map);
        } catch (Exception e) {
            return ResultTools.result(404, e.getMessage(), null);
        }
    }

}

启动项目,调用http://localhost:8080/api/test  不传任何参数,结果如下

表示接口已被拦截,token无效或是没传。

接下来我们做正确的操作:

先调用http://localhost:8080/login?userId=66 拿到用户token(假设用户id=66)

然后重新调用http://localhost:8080/api/test,这次我们带上token请求头

至此验证成功....

最后附上源码下载地址:https://download.csdn.net/download/qq_29370483/11192238

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值