我一直在使用JWT对用户进行身份验证并允许访问我正在工作的网站的某些区域时遇到问题。
确认用户存在于数据库中很好,我可以在后端创建令牌,没有任何问题,但当我尝试在拦截器中使用令牌时,它不起作用。这是我的登录功能。
getToken() {
// get token returns undefined
return this.token;
}
userLogin(email: string, password: string) {
const authData: AuthData = { email: email, password: password };
this.http.post<{ token: string }>('http://localhost:3000/api/auth/login', authData).subscribe((response) => {
const token = response.token;
this.token = token;
});
令牌被声明为私有变量,这就是为什么我在下面的拦截器中使用gettoken函数的原因。
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { UserAuthService } from './auth.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: UserAuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('auth-interceptor.ts intercept() Token = ', this.authService.getToken());
const authToken = this.authService.getToken();
const authRequest = req.clone({
headers: req.headers.set('Authorization', authToken)
});
return next.handle(authRequest);
}
}
如有任何帮助,我们将不胜感激,谢谢。
您需要在模块中提供拦截器:
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: MyInterceptor, multi: true }
]
如注释中所述,您应该确保您的服务中有@Injectable({providedIn: 'root'})
,否则该服务可能不是Singleton,并且您将拥有该类的多个实例。这可以解释令牌丢失的原因。
还有一个技巧,看看发生了什么,像这样更改代码:
private _token: string;
get token(): string {
console.log('getting token: ', this._token);
return this._token;
}
set token(token: string) {
console.log('setting token: ', token);
this._token = token;
}
然后您可以简单地执行this.token = token;
和const authToken = this.authService.token;
,您应该会看到日志。
还按顺序在服务构造函数中添加一个console.log()
,以便查看是否有同一服务的多个实例。