国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring Cloud Gateway自定義Token校驗(yàn)過濾器

2450184176 / 1730人閱讀

摘要:自定義校驗(yàn)全局過濾器如何應(yīng)用呢只需要添加注解,不需要進(jìn)行任何額外的配置,實(shí)現(xiàn)接口,自動(dòng)會對所有的路由起作用總結(jié)由于剛接觸,有些地方也不是特別熟悉,上面的示例代碼僅僅作為參考,如果有錯(cuò)誤的地方,還望指正。

一切的業(yè)務(wù)開發(fā)都是基于需求的,首先看看需求:

對訪問網(wǎng)關(guān)的請求進(jìn)行token校驗(yàn),只有當(dāng)token校驗(yàn)通過時(shí),才轉(zhuǎn)發(fā)到后端服務(wù),否則直接返回401

本文給出的示例代碼適用場景:

token存放在redis中, key為用戶的uid

依賴的pom.xml



    4.0.0

    com.winture
    api-gateway
    0.0.1-SNAPSHOT
    jar

    api-gateway
    Demo project for Spring Boot

    
        org.springframework.boot
        spring-boot-starter-parent
        2.0.4.RELEASE
         
    

    
        UTF-8
        UTF-8
        1.8
        Finchley.SR1
    

    
        
            org.springframework.cloud
            spring-cloud-starter-gateway
        

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

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

在Spring Cloud Gateway中,主要有兩種類型的過濾器:GlobalFilterGatewayFilter

GlobalFilter : 全局過濾器,對所有的路由均起作用

GatewayFilter : 只對指定的路由起作用

1、自定義GatewayFilter

自定義GatewayFilter又有兩種實(shí)現(xiàn)方式,一種是直接 實(shí)現(xiàn)GatewayFilter接口,另一種是 繼承AbstractGatewayFilterFactory類 ,任意選一種即可

1.1 實(shí)現(xiàn)GatewayFilter接口
package com.winture.gateway.filter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.StringRedisTemplate;
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.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * token校驗(yàn)過濾器
 * @Version V1.0
 */
public class AuthorizeGatewayFilter implements GatewayFilter, Ordered {

    private static final String AUTHORIZE_TOKEN = "token";
    private static final String AUTHORIZE_UID = "uid";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        String token = headers.getFirst(AUTHORIZE_TOKEN);
        String uid = headers.getFirst(AUTHORIZE_UID);
        if (token == null) {
            token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
        }
        if (uid == null) {
            uid = request.getQueryParams().getFirst(AUTHORIZE_UID);
        }

        ServerHttpResponse response = exchange.getResponse();
        if (StringUtils.isEmpty(token) || StringUtils.isEmpty(uid)) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        String authToken = stringRedisTemplate.opsForValue().get(uid);
        if (authToken == null || !authToken.equals(token)) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        return chain.filter(exchange);
    }

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

}

首先從header頭信息中獲取uid和token信息,如果token或者uid為null,則從請求參數(shù)中嘗試再次獲取,如果依然不存在token或者uid,則直接返回401狀態(tài)嗎,同時(shí)結(jié)束請求;如果兩者都存在,則根據(jù)uid從redis中讀取保存的authToken,并和請求中傳輸?shù)膖oken進(jìn)行比對,比對一樣則繼續(xù)通過過濾器鏈,否則直接結(jié)束請求,返回401.

如何應(yīng)用 AuthorizeGatewayFilter 呢?

package com.winture.gateway;

import com.winture.gateway.filter.AuthorizeGatewayFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes().route(r ->
                r.path("/user/list")
                .uri("http://localhost:8077/api/user/list")
                .filters(new AuthorizeGatewayFilter())
                .id("user-service"))
            .build();
    }
}
1.2 繼承AbstractGatewayFilterFactory類
package com.winture.gateway.filter.factory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
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.stereotype.Component;

import java.util.Arrays;
import java.util.List;

@Component
public class AuthorizeGatewayFilterFactory extends AbstractGatewayFilterFactory {

    private static final Log logger = LogFactory.getLog(AuthorizeGatewayFilterFactory.class);

    private static final String AUTHORIZE_TOKEN = "token";
    private static final String AUTHORIZE_UID = "uid";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public AuthorizeGatewayFilterFactory() {
        super(Config.class);
        logger.info("Loaded GatewayFilterFactory [Authorize]");
    }

    @Override
    public List shortcutFieldOrder() {
        return Arrays.asList("enabled");
    }

    @Override
    public GatewayFilter apply(AuthorizeGatewayFilterFactory.Config config) {
        return (exchange, chain) -> {
            if (!config.isEnabled()) {
                return chain.filter(exchange);
            }

            ServerHttpRequest request = exchange.getRequest();
            HttpHeaders headers = request.getHeaders();
            String token = headers.getFirst(AUTHORIZE_TOKEN);
            String uid = headers.getFirst(AUTHORIZE_UID);
            if (token == null) {
                token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
            }
            if (uid == null) {
                uid = request.getQueryParams().getFirst(AUTHORIZE_UID);
            }

            ServerHttpResponse response = exchange.getResponse();
            if (StringUtils.isEmpty(token) || StringUtils.isEmpty(uid)) {
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            String authToken = stringRedisTemplate.opsForValue().get(uid);
            if (authToken == null || !authToken.equals(token)) {
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            return chain.filter(exchange);
        };
    }

    public static class Config {
        // 控制是否開啟認(rèn)證
        private boolean enabled;

        public Config() {}

        public boolean isEnabled() {
            return enabled;
        }

        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
    }
}

如何應(yīng)用 AuthorizeGatewayFilterFactory 呢?

# 網(wǎng)關(guān)路由配置
spring:
  cloud:
    gateway:
      routes:
      - id: user-service
        uri: http://localhost:8077/api/user/list
        predicates:
        - Path=/user/list
        filters:
        # 關(guān)鍵在下面一句,值為true則開啟認(rèn)證,false則不開啟
        # 這種配置方式和spring cloud gateway內(nèi)置的GatewayFilterFactory一致
        - Authorize=true

上面的兩種方式都可以實(shí)現(xiàn)對訪問網(wǎng)關(guān)的 特定請求 進(jìn)行token校驗(yàn),如果想對 所有的請求 都進(jìn)行token校驗(yàn),那么可以采用實(shí)現(xiàn) GlobalFilter 方式。

2、自定義GlobalFilter
package com.winture.gateway.filter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.StringRedisTemplate;
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.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * token校驗(yàn)全局過濾器
 * @Version V1.0
 */
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
    private static final String AUTHORIZE_TOKEN = "token";
    private static final String AUTHORIZE_UID = "uid";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        String token = headers.getFirst(AUTHORIZE_TOKEN);
        String uid = headers.getFirst(AUTHORIZE_UID);
        if (token == null) {
            token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
        }
        if (uid == null) {
            uid = request.getQueryParams().getFirst(AUTHORIZE_UID);
        }

        ServerHttpResponse response = exchange.getResponse();
        if (StringUtils.isEmpty(token) || StringUtils.isEmpty(uid)) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        String authToken = stringRedisTemplate.opsForValue().get(uid);
        if (authToken == null || !authToken.equals(token)) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        return chain.filter(exchange);
    }

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

如何應(yīng)用 AuthorizeFilter 呢?

只需要添加 @Component 注解,不需要進(jìn)行任何額外的配置,實(shí)現(xiàn)GlobalFilter接口,自動(dòng)會對所有的路由起作用
3、總結(jié)

由于剛接觸Spring Cloud Gateway,有些地方也不是特別熟悉,上面的示例代碼僅僅作為參考,如果有錯(cuò)誤的地方,還望指正。

備注

運(yùn)行上面的代碼,需要先啟動(dòng)redis服務(wù),由于沒有配置redis的地址和端口,默認(rèn)采用localhost和6379端口,如果不一致,請自行在application.yml文件中配置即可;

網(wǎng)關(guān)的端口采用默認(rèn)的8080;

當(dāng)通過網(wǎng)關(guān)訪問/user/list時(shí),如果token驗(yàn)證通過,會轉(zhuǎn)發(fā)到 http://localhost:8077/api/user/list 上,這是另外的一個(gè)接口服務(wù),自行根據(jù)實(shí)際情況修改;

參考學(xué)習(xí):

Spring Cloud Gateway官方文檔

Spring Cloud Gateway源代碼

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/76929.html

相關(guān)文章

  • Spring Cloud Gateway 使用 Token 驗(yàn)證

    摘要:引入依賴自定義過濾器可以繼承或?qū)崿F(xiàn)實(shí)現(xiàn)過濾請求功能只能指定路徑上應(yīng)用去掉路徑的個(gè)前綴輸入過濾器類的名稱前綴可以在全局應(yīng)用 引入依賴 org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} ...

    Pikachu 評論0 收藏0
  • 服務(wù)網(wǎng)關(guān) Zuul 與 Redis 結(jié)合實(shí)現(xiàn) Token 權(quán)限校驗(yàn)

    摘要:項(xiàng)目地址本文將分四部分介紹登錄邏輯前置過濾器校驗(yàn)邏輯工具類演示驗(yàn)證一登錄邏輯登錄成功后,將生成的存儲在中。鍵是用戶值是二前置過濾器繼承自,必須實(shí)現(xiàn)的四個(gè)方法。 這兩天在寫項(xiàng)目的全局權(quán)限校驗(yàn),用 Zuul 作為服務(wù)網(wǎng)關(guān),在 Zuul 的前置過濾器里做的校驗(yàn)。 權(quán)限校驗(yàn)或者身份驗(yàn)證就不得不提 Token,目前 Token 的驗(yàn)證方式有很多種,有生成 Token 后將 Token 存儲在 R...

    flyer_dev 評論0 收藏0
  • [Spring cloud 一步步實(shí)現(xiàn)廣告系統(tǒng)] 6. Service實(shí)現(xiàn)&Zuul配置&a

    摘要:所以,沒必要過分糾結(jié)這種信息,咬文嚼字有時(shí)候反而會適得其反。若初通用錯(cuò)誤信息異常類請求參數(shù)異常用戶已存在用戶不存在在下面創(chuàng)建一個(gè)工具類用來對用戶進(jìn)行加密來獲取信息。工具類若初加密參考創(chuàng)建用戶的實(shí)現(xiàn),依次實(shí)現(xiàn)其他表操作。 DAO層設(shè)計(jì)實(shí)現(xiàn) 這里我們使用Spring DATA JPA來實(shí)現(xiàn)數(shù)據(jù)庫操作,當(dāng)然大家也可以使用Mybatis,都是一樣的,我們依然以用戶表操作為例: /** * A...

    孫淑建 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<