【问题标题】:How to handle the token before the page load?如何在页面加载之前处理令牌?
【发布时间】:2020-03-06 08:31:59
【问题描述】:

我使用 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);
            })
        );
    }
}

【问题讨论】:

  • 您是否在身份验证服务中使用了 Route Guard?
  • 我现在实现了 Route Guard,但问题是我在页面加载后得到了令牌

标签: node.js angular jwt


【解决方案1】:

您应该将代码分开。您的请求处理不应明确等待身份验证成功:相反,应使用 observables。

Auth0 help page 就是一个很好的例子。即使您不使用 Auth0 后端,架构也是一种选择:您的身份验证服务将令牌作为可观察对象返回,而您需要它的其他地方订阅可观察对象。

另外,you should not use localStorage to store your tokens 或 Cookies。相反,使用标准 OAuth 协议检索它(Okta、Auth0 等专用服务或开源替代方案提供了处理该问题的 SDK)。

例如Auth0 SDK:

为什么令牌没有存储在浏览器存储中?从历史上看,它是 常见于将令牌存储在本地或会话存储中。但是,浏览器 存储不是存储敏感数据的安全场所。这 auth0-spa-js SDK 为您管理会话检索,因此您无需 不再需要在浏览器存储中存储敏感数据,以便 刷新单页应用程序后恢复会话。

使用 auth0-spa-js,我们可以简单地从 SDK 请求令牌 我们需要它(例如,在 HTTP 拦截器中)而不是存储它 在 Angular 应用程序或浏览器中本地化。 SDK 管理令牌新鲜度 同样,因此我们无需担心更新令牌时 过期。

注意:我不隶属于 Auth0,只是在我的最新项目中使用了该服务:)

【讨论】:

  • 将 cookie 用于身份验证令牌也有不好的理由。无论哪种情况,您都必须考虑不同的安全问题,但都可以缓解。
  • 是的,使用标准客户端库可以很好地保证安全。
  • 对,我意识到我误解了 Auth0 SDK,他们实际上根本不存储令牌。在这个意义上编辑。
【解决方案2】:

等待的一种方法是通过 Promises - 拥有一个在您的身份验证返回之前不会解析的 Promise,然后在从 localStorage 访问您的令牌之前等待该 Promise。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    • 2013-10-10
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    相关资源
    最近更新 更多