使用geteway网关中的GlobalFilter过滤器进行token验证

GlobalFilter过滤器进行token验证

    • GlobalFilter过滤器代码部分
  • JwtFactory和redis的MAVEN依赖
    • JwtFactory生成token(身份令牌):代码部分
    • 工具类代码:
    • token认证认证部分代码:

GlobalFilter过滤器代码部分

import com.alibaba.fastjson.JSONObject;
import demo.utils.JwtConstant;
import demo.utils.JwtFactory;
import demo.utils.TokenCacheUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

@Configuration
public class IsLoginGateway implements GlobalFilter,Ordered {

    @Autowired
    private TokenCacheUtil tokenCacheUtil;

    @Override
    public int getOrder() {
        return 1;
    }

	//拉取token过期时间
    @Value("${token.expire:43200000}")
    @RefreshScope
    public void setExpire(Long expire) {
        if (expire != null) {
            JwtConstant.JWT_REFRESH_TTL = Long.valueOf(expire);
        }
    }

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        String userId = getLoginUserId(exchange);
        if (request.getMethod().name().equalsIgnoreCase("OPTIONS")) {
            JSONObject message = new JSONObject();
            message.put("statusCode", -1);
            message.put("msg", "请求类型错误!!!");
            byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
            DataBuffer buffer = response.bufferFactory().wrap(bits);
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //指定编码,否则在浏览器中会中文乱码
            response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
            return response.writeWith(Mono.just(buffer));
        }
        if (StringUtils.isNotBlank(userId)) {
            exchange.getResponse().getHeaders().set("isLogin", userId);
        } else {
            exchange.getResponse().getHeaders().set("isLogin", "-1");
            JSONObject message = new JSONObject();
            message.put("statusCode", -1);
            message.put("msg", "鉴权失败");
            byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
            DataBuffer buffer = response.bufferFactory().wrap(bits);
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //指定编码,否则在浏览器中会中文乱码
            response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
            return response.writeWith(Mono.just(buffer));
        }
        return chain.filter(exchange);
    }

    private String getLoginUserId(ServerWebExchange exchange) {
        String userId = null;
        String auth =exchange.getRequest().getHeaders().getFirst("Authorization");

        if ((auth != null) && (auth.length() > 7)) {
            Claims claims = JwtFactory.parseJWT(auth);
            if (claims != null) {
                userId = claims.get("userid") == null ? "" : claims.get("userid").toString();
                if (!tokenCacheUtil.checkTokenExists(auth, Integer.valueOf(userId))) {
                    return null;
                }
               exchange.getAttributes().put("userid",userId);
            }
        }
        return userId;
    }

}

JwtFactory和redis的MAVEN依赖

 
		
            io.jsonwebtoken
            jjwt
            0.7.0
        

        
        
            org.springframework.boot
            spring-boot-starter-data-redis
            1.5.13.RELEASE
        

JwtFactory生成token(身份令牌):代码部分

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;

/**
 * Description:
 * Created with edanelx.
 * Create in: 2018/3/29 07:20
 */
public class JwtFactory {
    public JwtFactory() {
    }

    private static SecretKey generalKey() {
        String stringKey = "Mpk4ZjZim2Q0Nj0xZDMpM2NhZlU0ZTgzMrYyN2IpZjY";
        byte[] encodedKey = Base64.encode(stringKey.getBytes()).getBytes();
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    public static Claims parseJWT(String jsonWebToken) {
        try {
            SecretKey key = generalKey();
            Claims claims = (Claims) Jwts.parser().setSigningKey(key).parseClaimsJws(jsonWebToken).getBody();
            return claims;
        } catch (Exception var3) {
            return null;
        }
    }

    public static String createJWT(String name, String userId) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey signingKey = generalKey();
        JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT").claim("unique_name", name).claim("userid", userId).setIssuer("pc.api.yobtc.com").setAudience("098f6bcd4621d373cade4e832627b4f6").setIssuedAt(now).signWith(signatureAlgorithm, signingKey);
        if (JwtConstant.JWT_REFRESH_TTL >= 0L) {
            long expMillis = nowMillis + JwtConstant.JWT_REFRESH_TTL;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp).setNotBefore(now);
        }

        return builder.compact();
    }
}

工具类代码:

public class JwtConstant
 {
   public static final String JWT_ID = "098f6bcd4621d373cade4e832627b4f6";

   public static final String JWT_NAME = "pc.api.yobtc.com";

   public static final String JWT_SECRET = "Mpk4ZjZim2Q0Nj0xZDMpM2NhZlU0ZTgzMrYyN2IpZjY";

   public static final int JWT_TTL = 3600000;

   public static final int JWT_REFRESH_INTERVAL = 3300000;
/* 15 */   public static long JWT_REFRESH_TTL = 3600000L;
 }


public class Constants {
    /*
     * token Key
     */
    public static final String TOKEN_KEY_PERFIX = "AUTH_TOKEN_";

    /**
     * 拦截器返回值:token错误
     */
    public static final int ERROR_RESPONSE_TOKEN_CODE = 1000;
    public static final String ERROR_RESPONSE_AUTH_TOKEN_TIMEOUT = "token过期,请重新登录";
    public static final String ERROR_RESPONSE_AUTH_PARSE = "无效的token";

}

token认证认证部分代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;

import java.util.concurrent.TimeUnit;

@Repository
public class TokenCacheUtil {

    @Autowired
    private StringRedisTemplate redisTemplate;

    /*@Value("${debug}")
    private boolean debug;*/

    private static final String CACHE_KEY_PREFIX = "user:token:pc:";

    private static final Integer[] BOSS_UID = new Integer[]{
            271498,
            427928,
            41458,
            246527,
            427190,
            393068,
            309,
            427837,
            427076,
            425074,
            710274,
            1066,
            832086,
            832082,
            832079,
            832081,
            832084,
            832078,
            832083,
            832080,
            832087,
            832092,
            832091,
            832094,
            832085,
            832265,
            832089,
            708432,
            708910,
            1000735,
            800361,
            1381946,
            1383092
    };

    private String getCacheKeyByUserId(Integer userId) {
        return CACHE_KEY_PREFIX + userId.toString();
    }

    public void saveToken(String token, Integer userId) {
        redisTemplate.opsForValue().set(getCacheKeyByUserId(userId), token);
//        redisTemplate.exp
        redisTemplate.expire(getCacheKeyByUserId(userId), new Long(JwtConstant.JWT_REFRESH_TTL / 1000),TimeUnit.SECONDS);
    }

    public boolean checkTokenExists(String token, Integer userId) {
        for (Integer uid : BOSS_UID) {
            if (uid.equals(userId)) {
                return true;
            }
        }
        
        String redisToken = redisTemplate.opsForValue().get(getCacheKeyByUserId(userId));
        return redisToken != null && redisToken.equals(token);
    }
}

你可能感兴趣的:(java技术)