我使用JWT进行身份验证(没有登录页面)。 我有一个问题,当站点加载时,首先启动的是获取方法,用于加载内容,然后是身份验证方法,然后将令牌保存在本地存储中。
问题是我收到未通过身份验证的错误,并且刷新页面后仍无法正常工作。 我需要让他先制定身份验证方法,然后将他保存到本地存储中,然后再加载页面。
身份验证服务:
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);
})
);
}
}
答案 0 :(得分:0)
您应该将代码分开。您的请求处理不应明确地等待身份验证成功:相反,请在各处使用可观察对象。
Auth0 help page是一个很好的例子。即使您不使用Auth0后端,该体系结构也是适合的架构:您的auth服务将令牌返回为可观察的令牌,并在需要它的其他地方订阅该令牌。
也可以使用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,只是在我的最新项目中使用了该服务:)
答案 1 :(得分:-1)
等待的一种方式是通过Promises-承诺直到您的身份验证返回后才能解决,然后等待该承诺,然后再从localStorage访问令牌。