Spring boot 集成jwt 实现请求认证(带有过期时间)

一、添加依赖



    io.jsonwebtoken
    jjwt
    0.9.0

二、编写 jwt 过滤器并进行 配置
 

JwtFilter 过滤器

package com.tnar.config;

import com.tnar.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author dzx
 * @ClassName:
 * @Description:
 * @date 2019年04月23日 15:05:21
 */
public class JwtFilter extends GenericFilterBean {


    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) res;
        String requestURI = request.getRequestURI();
        System.out.println("当前请求URI路径:"+requestURI);

        //如果是用户注册,登录,验证,同步操作则直接放行
        if(requestURI.startsWith("/tAcctCustOperate")){
            chain.doFilter(req, res);
            return;
        }

        //请求头中需要添加authorization字段
        final String authHeader = request.getHeader("authorization");

        // If the Http request is OPTIONS then just return the status code 200
        // which is HttpServletResponse.SC_OK in this code
        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            chain.doFilter(req, res);
        } else {
            //authorization 的 值,需要以Bearer 开头,否则认证不通过
            // Check the authorization, check if the token is started by "Bearer "
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                throw new ServletException("Missing or invalid Authorization header");
            }

            // Then get the JWT token from authorization
            final String token = authHeader.replaceFirst("Bearer", "").trim();

            try {
                // Use JWT parser to check if the signature is valid with the Key "secretkey"
                //final Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();
                final Claims claims = JwtUtil.parseJWT(token);
                // Add the claim to request header
                request.setAttribute("claims", claims);
            } catch (final SignatureException e) {
                throw new ServletException("Invalid token");
            }

            chain.doFilter(req, res);
        }
    }
}

JwtConfig 配置项

package com.tnar.config;

import org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author dzx
 * @ClassName:
 * @Description:
 * @date 2019年04月23日 14:58:30
 */
@Configuration
public class JwtConfig {

    @Bean
    public FilterRegistrationBean jwtFilter() {
        final FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new JwtFilter());
        registrationBean.addUrlPatterns("/*");
        System.out.println("加载jwt过滤器完成。。。。。。。。。。。。。");
        return registrationBean;
    }
}

JwtUtil 工具类,生成jwttoken ,以及解析 jwtToken 获取到 用户名,密码,过期时间信息等

package com.tnar.utils;

import com.alibaba.fastjson.JSON;
import com.oracle.xmlns.internal.webservices.jaxws_databinding.JavaWsdlMappingType;
import com.tnar.exception.MyException;
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;

public class JwtUtil {

    public static final long EXPIRATION_TIME = 3600_000_000L; // 1000 hour 有效期
    public static final String SECRET = "lambeter";//  密钥

    //解析
    public static Claims parseJWT(String jsonWebToken) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(DatatypeConverter.parseBase64Binary(SECRET))
                    .parseClaimsJws(jsonWebToken).getBody();
            return claims;
        } catch (Exception ex) {
            throw new MyException(ex.getMessage());
        }
    }

    //和时间有关的token
    public static String generateToken(Integer id, Date loginTime) {
        return MD5Util.getMD5ofStr((long)id + (loginTime == null ? 0L : Math.round(loginTime.getTime()/1000.0)) + SECRET);
    }

    //生成
    public static String createJWT(String userName, String password) {
        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());
        //添加构成JWT的参数
        JwtBuilder builder = Jwts.builder().setHeaderParam("type", "JWT")
                .claim("userName", userName)
                .claim("password", password)
                .signWith(signatureAlgorithm, signingKey);
        //添加Token过期时间
        long expMillis = nowMillis + EXPIRATION_TIME;
        Date exp = new Date(expMillis);
        builder.setExpiration(exp).setNotBefore(now);
        //生成JWT
        String jwtTokenStr = builder.compact();
        return jwtTokenStr;
    }


    public static void main(String[] args){
        String token = JwtUtil.createJWT("admin", "123456");
         System.out.println(token);
        Claims claims = JwtUtil.parseJWT(token);

       System.out.println(JSON.toJSONString(claims));

    }

}

三、测试过程 :

项目启动成功之后,访问 除了  /tAcctCustOperate/** 之外的其它任意接口,发现都会报以下错误,说明请求头中没有

jwtToken

Spring boot 集成jwt 实现请求认证(带有过期时间)_第1张图片 

然后我们 在登录的 时候 利用jwtUtil 生成 一个token

String jwtToken = JwtUtil.createJWT(userName,password);

之后将 token 返回 给 前端,前端下次在请求接口的时候,在 请求头中带上以下信息就可以通过认证,并成功访问接口了。

key 为  authorization ,value 为 Bearer(接一个空格) 开头的在登录的时候生成的jwtToken,过期时间为1000小时
Spring boot 集成jwt 实现请求认证(带有过期时间)_第2张图片

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