前后端分离 shiro+jwt

最近在弄前后端的项目,涉及到token验证的问题,记录一下。

shiro框架是公司提前配好的,详细的可以去看下配置文档,我这边只记录一下如何配置jwt。

首先添加maven的依赖包:

       <dependency>
            <!-- JSON Web Token Support -->
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>

        <!--ceshi-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>

创建filter类:

package com.qiyuansoft.unicorn.common.filter;



import com.qiyuansoft.unicorn.common.BusiException;
import com.qiyuansoft.unicorn.common.tools.JWTTool;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * 自定义token验证
 */
public class CustomerLogoutFilter extends LogoutFilter {
    private final static Logger log = LoggerFactory.getLogger(CustomerLogoutFilter.class);
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        String errmsg = "";
        try {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            String token = httpServletRequest.getHeader("Token");

            String appUID = JWTTool.getAppUID(token);
            return true;
        } catch ( BusiException ex) {
            return false;

        }
    }
}

jwt的工具类:

package com.qiyuansoft.unicorn.common.tools;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * APP登录Token的生成和解析
 *
 */
public class JWTTool {

    /** token秘钥,请勿泄露,请勿随便修改 */
    public static final String SECRET = "自己的私钥,随便设置";
    /** token 过期时间: 15 分钟 */
    public static final int CALENDARFIELD = Calendar.MINUTE;
    public static final int CALENDARINTERVAL = 1;

    /**
     * JWT生成Token.<br/>
     *
     * JWT构成: header, payload, signature
     *
     * @param userId
     *            登录成功后用户userId, 参数userId不可传空
     */
    public static String createToken(String userId) {
        Date iatDate = new Date();
        // expire time
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(CALENDARFIELD, CALENDARINTERVAL);
        Date expiresDate = nowTime.getTime();

        // header Map
        Map<String, Object> map = new HashMap<>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");

        /**
         * build token
         * param backups {iss:Service, aud:APP}
         *
         * withHeader : header
         * withClaim : payload
         * withIssuedAt : sign time
         * withExpiresAt : expire time
         * sign :signature
         */
        String token = JWT.create().withHeader(map)
                .withClaim("iss", "Service")
                .withClaim("aud", "APP")
                .withClaim("user_id", null == userId ? null : userId.toString())
                .withIssuedAt(iatDate)
                .withExpiresAt(expiresDate)
                .sign(Algorithm.HMAC256(SECRET));
        return token;

    }

    /**
     * 解密Token
     *
     * @param token
     * @return
     * @throws Exception
     */
    public static Map<String, Claim> verifyToken(String token) {
        DecodedJWT jwt = null;
        Map<String, Claim> claims = null;
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
            jwt = verifier.verify(token);
            claims = jwt.getClaims();
            Optional.ofNullable(claims).orElseThrow(IllegalArgumentException::new);
        } catch (Exception e) {
            // e.printStackTrace();
            // token 校验失败, 抛出Token验证非法异常
            System.out.println("IllegalArgumentException : token 校验失败");
        }
        return claims;
    }

    /**
     * 根据Token获取user_id
     *
     * @param token
     * @return user_id
     */
    public static String getAppUID(String token) {
        Map<String, Claim> claims = verifyToken(token);
        Claim userIdClaim = claims.get("user_id");
        if (null == userIdClaim || StringUtils.isEmpty(userIdClaim.asString())) {
            // token 校验失败, 抛出Token验证非法异常
        }
        return userIdClaim.asString();
    }

}

在shiro中配置filter过滤器:

拦截

filterChainDefinitionMap.put("/*", "logout");// 拦截验证token
filterChainDefinitionMap.put("/**", "logout");
filterChainDefinitionMap.put("/*.*", "logout");

进入filter

包 import javax.servlet.Filter;

Map<String, Filter> filters = new HashMap<>();
filters.put("logout", new CustomerLogoutFilter());
filterFactoryBean.setFilters(filters);

上边是jwt验证token,token的创建在登陆成功的时候调用工具类生成返回前端,后续发送请求的时候前台带过来。

生成token需要带上你的用户id
token = JWTTool.createToken(user.getId());


token是根据你的用户id加上秘钥还有时间戳生成的,解密的时候回返回给你用户id。判断一下这个用户id不为空并且和你的当前用户的id一样就可以了。

辛勤的汗水换来的肯定是美好的未来,加油哦。

猜你喜欢

转载自blog.csdn.net/qq_41992943/article/details/103402545