因自定义注解白名单过滤造成gateway解析不到用户ID的问题

@IgnoreUrlsAnnon("/list")
@IgnoreUrlsAnnon("/test")
自定义注解:慎用/list、/test等通用名称,会过滤掉所有/list、/test等方法的token获取。
getApiUserId():取不到值,会被过滤掉。
getUidByToken(httpServletRequest):可以取到值。
getApiUserIdNew():可以取到值。

BaseController.java

    /**
     * 获得 C端登录人用户id
     *
     * @return result
     */
    protected Integer getApiUserId() {
        int intHeader = request.getIntHeader(JwtAdminInfo.apiUserId);
        return Math.max(intHeader, 0);
    }

    /**
     * 获得 C端登录人用户id
     *
     * @return result
     */
    protected Long getApiUserIdNew() {
        String token = request.getHeader(Header.AUTHORIZATION.getValue());
        if (StrUtil.isEmpty(token)) {
            return 0L;
        }
        Claims claimsFromToken = JwtTokenUtil.getClaimsFromToken(token);
        String apiUserId = claimsFromToken.get(JwtAdminInfo.apiUserId).toString();
        return Long.valueOf(apiUserId);
    }

TestController.java 

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import com.alibaba.fastjson.JSON;
import BaseController;
import JwtAdminInfo;
import JwtTokenUtil;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Map;

/**
 * @author author
 */
@Api(tags = {"C端--token解析测试"})
@RestController
@RequestMapping("/api/test")
@Slf4j
public class TestController extends BaseController {
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @PostMapping("/test")
    @ApiOperation("测试")
    public void test(HttpServletRequest httpServletRequest) {
        TestRequest testRequest = new TestRequest();
        //token解析用户ID--方法一
        Long apiUserId = getApiUserId().longValue();
        //token解析用户ID--方法二
        Long uid = getApiUserIdNew();
        log.info("token获取的uid:[{}], gateway获取的uid:[{}]", uid, apiUserId);
        testRequest.setUid(uid);
        if (!apiUserId.equals(uid)) {
            log.error("token获取的uid:[{}], gateway获取的uid:[{}]", uid, apiUserId);
            // 临时添加日志到redis用于gateway错误排查
            addRedisLog(testRequest, httpServletRequest);
        }
    }

    //token解析用户ID -- 方法二
    private Long getUidByToken(HttpServletRequest httpServletRequest) {
        String token = httpServletRequest.getHeader(Header.AUTHORIZATION.getValue());
        if (StrUtil.isEmpty(token)) {
            return 0L;
        }
        Claims claimsFromToken = JwtTokenUtil.getClaimsFromToken(token);
        String apiUserId = claimsFromToken.get(JwtAdminInfo.apiUserId).toString();
        return Long.valueOf(apiUserId);
    }

    /**
     * 临时添加到redis的用于排查gateway问题的日志
     *
     * @param testRequest
     * @param httpServletRequest
     */
    private void addRedisLog(TestRequest testRequest, HttpServletRequest httpServletRequest) {
        //token解析用户ID -- 方法二
        Long newApiUserId = getUidByToken(httpServletRequest);
        Map<String, Object> map = new HashMap<>();
        Enumeration<String> enumeration = httpServletRequest.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String key = enumeration.nextElement();
            map.put(key, httpServletRequest.getHeader(key));
        }
        map.put("uid", "token获取的uid:[" + newApiUserId + "], gateway获取的uid:[" + getApiUserId() + "],");
        map.put("TestRequest", testRequest);
        redisTemplate.opsForValue().set("TestError::uid-"
                .concat(newApiUserId.toString())
                .concat("-")
                .concat(String.valueOf(System.currentTimeMillis())), JSON.toJSONString(map));
    }
}

TestRequest.java

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * @author author
 */
@Data
public class TestRequest {
    @ApiModelProperty(value = "用户ID")
    private Long uid;
}

JwtAdminInfo.java

public class JwtAdminInfo {
    public static final String apiUserId = "apiUserId";
}

 JwtTokenUtil.java

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

import java.util.Date;
import java.util.Map;

/**
 * JwtToken生成的工具类
 * JWT token的格式:header.payload.signature
 * header的格式(算法、token的类型):
 * {"alg": "HS512","typ": "JWT"}
 * payload的格式(用户名、创建时间、生成时间):
 * {"sub":"wang","created":1489079981393,"exp":1489684781}
 * signature的生成算法:
 * HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
 */
public class JwtTokenUtil {
    public static String prefix = "JwtToken:";
    private static String secret = "test_12345678910987654321";

    /**
     * 根据负责生成JWT的token
     */
    public static String generateToken(Map<String, Object> claims) {
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(generateExpirationDate())
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    /**
     * 从token中获取JWT中的负载
     */
    public static Claims getClaimsFromToken(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            e.fillInStackTrace();
        }
        return claims;
    }

    /**
     * 生成token的过期时间
     */
    public static Date generateExpirationDate() {
        return new Date(33156026044000l);
    }

    /**
     * 从token中获取登录用户名
     */
    public static String getUserNameFromToken(String token) {
        String username;
        try {
            Claims claims = getClaimsFromToken(token);
            username = claims.getSubject();
        } catch (Exception e) {
            username = null;
        }
        return username;
    }

    /**
     * 判断token是否已经失效
     */
    private static boolean isTokenExpired(String token) {
        Date expiredDate = getExpiredDateFromToken(token);
        return expiredDate.before(new Date());
    }

    /**
     * 从token中获取过期时间
     */
    private static Date getExpiredDateFromToken(String token) {
        Claims claims = getClaimsFromToken(token);
        return claims.getExpiration();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值