1

我们在同一台开发机器上的不同端口上有一个 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 服务中设置了推荐的标头。

4

1 回答 1

0

您的localhost连接必须是安全的 ( https )。这是必需的!

您需要创建 SSL 证书并在您的 Angular 应用程序中使用,如此处所述

就我而言,当我使用 SSL 证书重新启动我的 Angular 应用程序时,refresh_token 会自动在请求标头中发送(作为“cookie”属性)。

于 2021-09-24T09:18:06.367 回答