Node.js 如何在页面加载之前处理令牌?

Node.js 如何在页面加载之前处理令牌?,node.js,angular,jwt,Node.js,Angular,Jwt,我使用JWT进行身份验证,无需登录页面。 我有一些问题,当站点加载时,首先开始的是加载内容的get方法,然后是身份验证方法,并将令牌保存在本地存储中 问题是我得到的错误,我没有认证,并在我刷新页面后,它的工作。 我需要让他首先使用身份验证方法并将其保存到本地存储,然后加载页面 身份验证服务: import { Injectable } from '@angular/core'; import { HttpService } from '../http/http.service'; import

我使用JWT进行身份验证,无需登录页面。 我有一些问题,当站点加载时,首先开始的是加载内容的get方法,然后是身份验证方法,并将令牌保存在本地存储中

问题是我得到的错误,我没有认证,并在我刷新页面后,它的工作。 我需要让他首先使用身份验证方法并将其保存到本地存储,然后加载页面

身份验证服务:

import { Injectable } from '@angular/core';
import { HttpService } from '../http/http.service';
import * as jwt_decode from 'jwt-decode';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  public isDialogOpen = false;

  constructor(private http: HttpService) { }

  authUser(userID) {
    if (localStorage.getItem('token') === null) {
      this.http.authUser(userID).subscribe((data) => {
        localStorage.setItem('token', data.token);
      }, error => {
        console.log(error);
      });
    }
  }

  removeToken() {
    localStorage.clear();
  }

  getCurrentUser() {
    try {
      const jwt = localStorage.getItem('token');
      return jwt_decode(jwt);
    } catch (error) {
      return null;
    }
  }
}
header.interceptor:

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';

@Injectable()
export class HeaderInterceptor implements HttpInterceptor {
    constructor(public authService: AuthService) { }
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const token = localStorage.token;
        if (!token) {
          return next.handle(request);
        }

        request = request.clone({
            setHeaders: {
                'Content-Type': 'application/json',
                'x-auth-token': token
            }
        });
        return next.handle(request);
    }
}
Error.interceptor.ts:

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { AuthService } from '../services/auth.service';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
    constructor(public authService: AuthService) { }
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
            catchError(err => {
                if (err) {
                    console.log(`Server Error`);
                }
                if (err.status === 401) {
                    this.authService.authUser('1');
                }
                const error = err.error.message || err.statusText;
                return throwError(error);
            })
        );
    }
}

你应该把你的代码分开。您的请求处理不应该显式地等待身份验证成功:相反,应该在所有地方使用可观察的

如何做到这一点的一个很好的例子是。即使您不使用Auth0后端,该体系结构也是一个值得追求的体系结构:您的auth服务将令牌作为可观察对象返回,而您需要它的其他地方则订阅可观察对象

还有,或者是饼干。取而代之的是,使用标准OAuth协议专用服务(如Okta、Auth0或开源替代方案)检索它,这些服务提供SDK来处理这些问题

例如:

为什么令牌不存储在浏览器存储中?历史上,它是 用于将令牌存储在本地或会话存储中的公用项。但是,浏览器 存储不是存储敏感数据的安全场所。这个 auth0 spa js SDK为您管理会话检索,这样您就不会 不再需要将敏感数据存储在浏览器存储器中,以便 刷新单页应用程序后还原会话

使用auth0 spa js,我们可以在需要时从SDK请求令牌 我们需要它,例如,在HTTP拦截器中,而不是存储它 在Angular应用程序或浏览器中本地显示。SDK管理令牌新鲜度 同样,我们也不需要担心代币到期时的续期问题 到期


注意:我没有加入Auth0,只是在我的最新项目中使用了该服务:

等待的一种方式是通过承诺-承诺在验证返回之前不会解决,然后等待该承诺,然后再从localStorage访问令牌

您的身份验证服务是否使用了Route Guard?我现在实现了Route Guard,但问题是我在页面加载后获得了令牌也有不好的理由对身份验证令牌使用cookie。在这两种情况下,您都必须考虑不同的安全问题,但两者都可以减轻。是的,使用标准客户端库是确保安全的良好保证。对,我意识到我误解了Auth0SDK,它们实际上根本不存储令牌。在这个意义上编辑。