首页 > 解决方案 > jquery ajax 请求未将 cookie 从 jsp 和 servlet 应用程序发送到 Spring Cloud api 网关应用程序

问题描述

如果用户成功通过身份验证,整体 JSP servlet 应用程序会将 oauth2 访问令牌和刷新令牌保存在 cookie 中,如以下代码所示。

在此处输入图像描述

if(authenticated) {
                    String accessToken = getUserAccessToken(userStr,passStr);
                    if(!accessToken.isEmpty()) {
                    Cookie cookie = new Cookie("access_token", accessToken);
                    cookie.setPath("/");
                    //cookie.setHttpOnly(true);
                    cookie.setDomain("localhost");
                    //TODO: When in production must do cookie.setSecure(true);
                    cookie.setMaxAge(3600);
                    response.setHeader("Access-Control-Allow-Credentials", "true");
                    response.setHeader("Access-Control-Allow-Origin", "http://localhost:8081");
                    response.addCookie(cookie);
                    }
                    
                    if(!refreshToken.isEmpty()) {
                        Cookie cookie = new Cookie("refresh_token", refreshToken);
                        cookie.setPath("/");
                        //cookie.setHttpOnly(true);
                        cookie.setDomain("localhost");
                        //TODO: When in production must do cookie.setSecure(true);
                        cookie.setMaxAge(10000);
                        response.setHeader("Access-Control-Allow-Credentials", "true");
                        response.setHeader("Access-Control-Allow-Origin", "http://localhost:8081");
                        response.addCookie(cookie);
                    }
                }

monolith jsp 和 servlet 应用程序通过 spring 云网关向微服务应用程序发送 ajax 请求,如下面的代码所示。

var token = readCookie('access_token');


$.ajax({
                type: "POST",
                enctype: 'multipart/form-data',
                url: "http://localhost:8081/api/v1/users/bulkUpload",
                xhrFields: {
                    withCredentials: true
                },
                data: newData,
                processData: false,
                contentType: false,
                crossDomain: true,
                cache: false,
                timeout: 600000,
                success: function (data) {


........
                    
                    
                    
                },
                error: function (e) {
                   
                },
                beforeSend: function (xhr) {
                    xhr.setRequestHeader('Authorization', 'Bearer ' + token);
                    xhr.setRequestHeader('Access-Control-Allow-Credentials', 'true');
                    $('body').addClass("loading");
                }
                
            });

monolith jsp 和 servlet 应用程序在 jboss 服务器(http://localhost:8080)的端口 8080 上运行,apigateway 在嵌入式 tomcat 服务器的端口 8081 上运行(http://localhost:8081)。

在 Spring Cloud Gateway 中,我实现了一个过滤器来捕获从单体应用程序 AJAX 请求发送的 cookie 和标头,如下所示。

@Component
public class AccessTokenCheckingGlobalFilterPre extends AbstractGatewayFilterFactory<AccessTokenCheckingGlobalFilterPre.Config> {

    

    public AccessTokenCheckingGlobalFilterPre() {
        super(AccessTokenCheckingGlobalFilterPre.Config.class);
    }

    @Override
    public GatewayFilter apply(AccessTokenCheckingGlobalFilterPre.Config config) {
        return (exchange, chain) -> {
             Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
             ServerHttpRequest request = null;
             if (route != null) {
                
                
                 request = exchange.getRequest();
                 ServerHttpResponse response = exchange.getResponse();
                 
                 HttpHeaders headers = request.getHeaders(); **// cookies not contained in headers**
                 List<String> authorizationHeader = headers.get(HttpHeaders.AUTHORIZATION);
                 String value = authorizationHeader.get(0);
                 
                 MultiValueMap<String, HttpCookie> cookies = request.getCookies(); **// cookies null**

                
                 
             }
             
             return chain.filter(exchange.mutate().request(request).build());
            
            
            
        };
    }

    public static class Config {

    }
}

但是这个请求对象

请求 = exchange.getRequest();

不包含任何 cookie,它为空。cookie 也不包含在标头中。为什么 cookie 没有通过 ajax 请求发送到 apigateway 端。

标签: jqueryajaxspring-bootspring-cloud-gateway

解决方案


推荐阅读