Angular 请求中的通用集 set-cookies header

Angular Universal set set-cookies in request header

我有带身份验证的 Angular 通用 SSR 应用程序。我将身份验证令牌保存在 http cookies(set-cookies) 中。现在,当我刷新应用程序时,我首先看到未经身份验证的页面,一秒钟后它转换为经过身份验证的状态。

我知道发生这种情况是因为 Universals 渲染器服务器在渲染页面时没有将令牌从 cookie 传递到 API。那么我如何才能强制通用服务器以经过身份验证的状态呈现页面?

Angular universal 在使用 HttpClient (github issue) 时不传输 cookie。您可以使用拦截器手动添加它们。

interceptor.ts

import { REQUEST } from '@nguniversal/express-engine/tokens';

@Injectable()
export class CookieInterceptor implements HttpInterceptor {
  constructor(@Optional() @Inject(REQUEST) private httpRequest) 
  {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler) {
    if (this.httpRequest) //If optional request is provided, we are server side
    {
      req = req.clone(
      { 
        setHeaders: 
        {
            Cookie: this.httpRequest.headers.cookie
        }
      });
    }
    return next.handle(req);
  }
}

您可能会遇到以下错误

Refused to set unsafe header 'Cookie'

在此 comment 中建议的一种可能的解决方法是绕过 xhr2 的默认安全行为以应对不安全 headers

对于 angular 7(我猜是 8),以下工作

server.ts

import * as xhr2 from 'xhr2';
xhr2.prototype._restrictedHeaders = {};

我还没有测试 angular 9,但我认为你需要一个 different workaround 用于不安全的 cookie header

// activate cookie for server-side rendering
export class ServerXhr implements XhrFactory {
  build(): XMLHttpRequest {
    xhr2.prototype._restrictedHeaders.cookie = false;
    return new xhr2.XMLHttpRequest();
  }
}

@NgModule({
  ...
  providers: [{ provide: XhrFactory, useClass: ServerXhr }],
  ...
})
export class AppServerModule {}