jquery - 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 端。
解决方案
推荐阅读
- python - 如何使用 Tkinter 按钮正确打开网络浏览器?
- ios - Twilio 函数错误 20429 - 请求多条短信
- google-sheets - 查询无法在同一查询中同时提取单词和整数
- php - 我正在使用将图像插入 mysqli 数据库的富文本编辑器,我想将图像提取到文件中
- pandas - 从 tar.gz 文件夹中读取 json 文件并转换为 pandas 数据框
- git - 我真的需要在 .gitattributes 中指定所有二进制文件吗
- sql - SQL用于存储特定范围内从冷到热的数字?
- swift - 如何重新排序 Realm LinkingObjects 中的元素?
- azure-web-app-service - 如何为 azure 网站设置多个主机名
- mariadb - 在同一会话上创建不同的临时表时,存储过程返回“错误代码:1054。‘字段列表’中的未知列‘schema.table.col’”