【发布时间】:2019-03-02 08:38:03
【问题描述】:
与Why does Chrome ignore Set-Cookie header? 相同,但我提供了我正在使用的框架的代码。
这是我的原文,我把它作为上面的答案(不是真正的答案,但它确实提供了一些所要求的代码,但系统操作员告诉我,因为这不是答案,我应该再次提出这个问题。所以这里...
我已经被困在这个问题上太久了。在 Postman、Firefox 等中一切正常,但 Chrome 顽固地拒绝接受 Set-Cookie 标头。
我的服务器(Spring Zuul 代理)
@Bean
public CorsFilter corsFilter() {
logger.info("=================> corsFilter intialization.");
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedOrigins(Collections.singletonList("http://neptune.local.mydoman.org:4200"));
config.setAllowedHeaders(Collections.singletonList("*"));
config.setAllowedMethods(Arrays.stream(HttpMethod.values()).map(HttpMethod::name).collect(Collectors.toList()));
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
相当开放,但不担心,一旦它工作,我会收紧。
我想将 refresh_token 存储在仅限 HTTP 的 cookie 中,我已经放宽了它以测试是否设置了 cookie。
我的 PostFilter 在发送响应之前设置 cookie。
@Component
公共类 CustomPostZuulFilter 扩展 ZuulFilter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final ObjectMapper mapper = new ObjectMapper();
// Default is 30 days
@Value("${oauth.http.cookie.maxAge:2592000}")
private int cookieMaxAge;
@Override
public Object run() {
final RequestContext ctx = RequestContext.getCurrentContext();
logger.info("PostZuulFilter called: " + ctx.getRequest().getRequestURI());
final String requestURI = ctx.getRequest().getRequestURI();
final String requestMethod = ctx.getRequest().getMethod();
try {
final InputStream is = ctx.getResponseDataStream();
String responseBody = IOUtils.toString(is, "UTF-8");
if (responseBody.contains("refresh_token")) {
final Map<String, Object> responseMap =
mapper.readValue(responseBody,
new TypeReference<Map<String, Object>>() {
});
final String refreshToken = responseMap.get("refresh_token").toString();
logger.info("Decoding refresh token from response.");
decodeJwtToken(refreshToken);
responseMap.remove("refresh_token");
responseBody = mapper.writeValueAsString(responseMap);
final Cookie cookie = new Cookie("refreshToken", refreshToken);
// cookie.setHttpOnly(true);
// cookie.setSecure(true);
cookie.setPath(ctx.getRequest().getContextPath() + "/oauth/token");
cookie.setMaxAge(cookieMaxAge); // 30 days
ctx.getResponse().addCookie(cookie);
logger.info("PostZuulFilter refresh token now stored in HTTP ONLY cookie:");
logger.info(refreshToken);
}
if (requestURI.contains("oauth/token") && requestMethod.equals("DELETE")) {
final Cookie cookie = new Cookie("refreshToken", "");
cookie.setMaxAge(0);
cookie.setPath(ctx.getRequest().getContextPath() + "/oauth/token");
ctx.getResponse().addCookie(cookie);
}
ctx.setResponseBody(responseBody);
} catch (final IOException e) {
logger.error("Error occured in zuul post filter", e);
}
return null;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public int filterOrder() {
return 10;
}
@Override
public String filterType() {
return "post";
}
private String decodeJwtToken(String jwtToken) {
logger.info("------------ Decode JWT ------------");
String[] split_string = jwtToken.split("\\.");
String base64EncodedHeader = split_string[0];
String base64EncodedBody = split_string[1];
String base64EncodedSignature = split_string[2];
logger.info("~~~~~~~~~ JWT Header ~~~~~~~");
Base64 base64Url = new Base64(true);
String header = new String(base64Url.decode(base64EncodedHeader));
System.out.println("JWT Header : " + header);
logger.info("~~~~~~~~~ JWT Body ~~~~~~~");
String body = new String(base64Url.decode(base64EncodedBody));
logger.info("JWT Body : "+body);
return "";
}
}
最后是我的 Angular 服务请求。
public obtainAccessToken(params: URLSearchParams): Observable<string> {
console.log('obtainAccessToken');
console.log('Getting access token from ', appConfig.tokenServerUrl);
console.log('Using params: ');
console.dir(params.toString());
// Now fire the request
this.http.post(
'http://neptune.local.domain.org:8084/oauth/token',
params.toString(), {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'}),
withCredentials: true,
observe: 'response'
})
.pipe(map((response) => {
// Try and find the Set-Cookie header! (Good luck)
console.log(response);
console.log('response headers',response.headers.keys());
const respKeySet = response.headers.keys();
for( let x = 0; x < respKeySet.length; x++ ) {
console.log('Key: %s, Value: %s',
respKeySet[x],
response.headers.get(respKeySet[x]));
}
}));
}
我的服务器和我的客户端在同一个工作站上运行,我设置了 FQD 名称。
所以客户端正在运行。 http://neptune.local.mydomain.org:4200
我的服务器正在运行。 http://neptune.local.mydomain.org:8084
我从来没有在 Chrome 中得到 Set-Cookie???
有人知道为什么吗? 呃,求助……
【问题讨论】: