spring cloud gateway部署到k8s上UrlEncode問題

問題

k8singress使用的是ingress-nginx.

項目中用到了spring cloud gatewayAPI網關,部署環境有dockerk8s等. 測試出現一個問題:
請求的URL路徑中如果出現了中文參數,如http://localhost:8080/test?param=你好,如果部署在docker或者裸機上,後臺服務接收到的參數param你好,但是如果部署在k8s上,後臺接收到的參數可能是UrlEncode之後的%E4%BD%A0%E5%A5%BD,這不是後臺需要的. 雖然可以在後臺通過URLDecoder.decode(name, "UTF-8")強制解碼,不過比較麻煩.

分析

測試中發現,

  • 如果直接將後臺服務部署到k8s上,通過service -> ingress暴露出來,不管是通過k8sClusterIP,如http://10.96.240.18:8080/test?param=你好, 還是通過ingress域名http://local.com/test?param=你好請求後臺服務,後臺能夠正確接收到參數爲你好,證明問題可能不是因爲部署在k8s上造成的,只可能是spring cloud gatewayAPI網關原因;
  • 但是部署在docker或者裸機上,通過spring cloud gateway網關請求後臺服務,後臺能夠正確接收到參數爲你好,證明網關也是沒有問題的,問題只可能是部署環境k8s的原因;
  • 如果將網關服務部署到k8s上,又有兩種情況:
    • 通過ingress域名請求網關 -> 後臺,後臺接收到的參數是%E4%BD%A0%E5%A5%BD,看似是網關的問題;
    • 通過ClusterIP請求網關 -> 後臺,後臺接收到的參數是你好,這又證明網關沒問題,看似是ingress的問題,但前面也證明了ingress可以正確傳遞中文字符,非常的奇怪!
  • spring cloud gateway中所有的Filter全部註釋掉,發現通過ingress域名請求網關 -> 後臺,後臺也能正確的接收到中文參數,證明還是網關的問題,而且這個問題只有部署在k8s中搭配ingress-nginx使用時纔會暴露.

解決

依次將註釋掉的Filter加回去,證明問題出現在class XXXX extends ForwardedHeaderFilter這個類上.這個類用於設置網關跨域訪問和網關本身接口權限驗證.

測試發現,即使只註釋成下面這樣,還是會有問題,但是註釋掉@Component,就沒有問題.應該是super.filter(exchange, chain)父類這個方法有問題.

@Component
@Slf4j
public class AuthTokenFilter extends ForwardedHeaderFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        //跨域問題 接口權限驗證 TODO
        return super.filter(exchange, chain);
    }
}

改成下面這樣測試可以解決問題.

@Component
@Slf4j
public class AuthTokenFilter extends ForwardedHeaderFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        //跨域問題 接口權限驗證 TODO
        return chain.filter(exchange);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章