我们在同一台开发机器上的不同端口上有一个 Angular 前端和一个 Web 服务。Web 服务配置为允许从 localhost 和托管 Angular 应用程序的端口进行访问。
我们正在使用 JWT 身份验证,它适用于针对 Web 服务的初始身份验证。我们收到一个身份验证令牌并将其存储在 Angular 本地存储中,以及一个刷新令牌,该令牌存储为设置了 HttpOnly 的 cookie。目前我们处于一个开发环境中,在客户端或 Web 服务上都没有启用 SSL。
当我们的身份验证令牌过期时,问题就来了。我们的应用程序发送更新令牌的请求,但该请求没有刷新令牌 cookie。
我们尝试在 Angular 中设置代理,将 API 请求从 Angular 域转发到 Web 服务。在这种情况下,刷新令牌 cookie 被转发到 Web 服务,我们得到新的令牌。不幸的是,在构建和部署应用程序之后,这将不起作用,我们需要能够在未启用 SSL 的环境中部署和开发。
这是我们的 Angular 应用程序中处理发送刷新令牌的相关代码。下面是授权服务中调用的方法。
public refreshToken() {
return this.http.post(this.appConfigService.getGrouperWebServiceUrl()+'/auth/refresh', {})
.pipe(
map((res: LoginResponse) => {
this.setSession(res);
return res;
})
);
}
POST 请求被 Angular 拦截器拦截。
intercept(req: HttpRequest < any > , next: HttpHandler):
Observable < HttpEvent < any >> {
// ...
if (req.url.indexOf('refresh') !== -1) {
console.log("token interceptor: refresh");
return next.handle(this.configureRefresh(req));
}
// ...
}
configureRefresh(req: HttpRequest < any > ) {
return req.clone({
withCredentials: true
});
}
下面是使用 Angular 代理的刷新请求的原始请求,因此该请求似乎来自与 Web 服务相同的来源。请注意,refreshToken cookie 包含在请求中。
POST /proxy/auth/refresh HTTP/1.1
Host: localhost:4200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 2
Origin: http://localhost:4200
Connection: keep-alive
Referer: http://localhost:4200/userHome
Cookie: refreshToken=/*token redacted*/
下面是在没有代理的情况下进行刷新的原始请求。请注意,请求中不包含 refreshToken cookie。
POST /auth/refresh HTTP/1.1
Host: localhost:8081
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 2
Origin: http://localhost:4200
Connection: keep-alive
Referer: http://localhost:4200/userHome
当我们进行跨域请求时,如何让 refreshToken cookie 包含在请求标头中?
我们确实看到了这个响应https://stackoverflow.com/a/46412839/8517076,但它似乎没有帮助。我们已经在 Web 服务中设置了推荐的标头。