我有一个为 Angular 4 编写的可注入(inject) 身份验证服务。代码类似于以下内容:
auth.service.ts
import { CookieService } from 'ngx-cookie';
import { Identity } from './auth.identity';
export function authInit(authService: AuthService): () => Promise<any> {
return (): Promise<any> => authService.checkAuthenticated();
}
@Injectable()
export class AuthService {
identity: Identity;
isAuthenticated:boolean = false;
apiUrl: string = 'https://myUrl/api';
constructor(private _http: HttpClient, private _cookieService: CookieService) {
this.identity = new Identity();
}
checkAuthenticated(): Promise<any> {
return new Promise((res, rej) => {
let identity = this._cookieService.getObject('myToken');
if (!!identity) {
this.setAuthenticated(identity);
}
});
}
login(username: string, password: string) {
let creds = {
username: username,
password: password
};
this._http.post<any>(this.apiUrl + '/auth/login', creds).subscribe(data => {
this.setAuthenticated(data);
});
}
logout() {
}
private setAuthenticated(data: any) {
this._cookieService.putObject('myToken', data);
this.isAuthenticated = true;
// hydrate identity object
}
}
auth.module.ts
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AuthService, authInit } from './auth.service';
@NgModule({
imports: [CommonModule],
providers: [
AuthService,
{
provide: APP_INITIALIZER,
useFactory: authInit,
deps: [AuthService],
multi: true
}
]
})
export class AuthModule { }
我的想法是,当应用程序加载时,我希望能够检查本地存储(cookie、sessionStorage 或 localStorage)以查看该值是否存在。 (这由构造函数中注释的 if
语句演示。)基于 isAuthenticated
属性,我希望能够显示特定内容。
目前,如果我取消注释构造函数中的行,我将得到一个异常document.* is not defined
。我知道那是什么意思。不幸的是,我不知道如何实现我的目标。
请记住,这是一个服务而非 View 组件,因此没有可用的 ngOnInit
方法。
已编辑
所以我按照建议添加了工厂提供者。但是,我仍然遇到异常:document is not defined
谢谢!
最佳答案
当您有一个服务需要在其他所有内容初始化之前运行时,您可以使用 APP_INITIALIZER token (至少可以说文档很少:)
要点是在您的应用程序提供程序数组中添加一个 factory provider :
{
provide: APP_INITIALIZER,
useFactory: authInit,
deps: [AuthService],
multi: true
}
确保专门为 APP_INITIALIZER 提供设置,并将多值设置为 true。 authInit 函数是一个工厂,它返回一个返回 promise 的函数。它必须返回一个 promise 而不是一个可观察的。它会是这样的:
export function authInit(authServ: AuthService) {
return () => authServ.check();
}
您可以在 authServ.check() 函数中放置您当前在服务中评论的逻辑(只需确保它返回一个 promise 作为结果)。以这种方式设置将使该逻辑在应用程序加载时运行。
编辑:现在我看一下 app.module.ts 添加 initialization of the cookie service并添加 BrowserModule :
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { CookieModule } from 'ngx-cookie';
import { AuthService, authInit } from './auth.service';
@NgModule({
imports: [BrowserModule, CommonModule, CookieModule.forRoot()],
providers: [
AuthService,
{
provide: APP_INITIALIZER,
useFactory: authInit,
deps: [AuthService],
multi: true
}
]
})
export class AuthModule { }
此外,请确保将 ngx-cookie 添加到您的 systemjs.config.js(如果您将其用作加载程序)。
关于javascript - Angular 4 和 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46965822/