javascript - Angular 4 和 token

标签 javascript angular

我有一个为 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/

相关文章:

JavaScript,使用 indexOf() 和 lastIndexOf() 方法查找数组实例

javascript - 在我的案例中如何禁用拖动功能?

javascript - 如何在 ionic 4 中移动搜索栏右侧搜索栏的搜索图标

typescript - 如何在 Angular 2 typescript 应用程序中使用 moment.js 库?

javascript - 显示一个 &lt;input type ="checkbox"> 元素,中间有一个框而不是复选标记

javascript - 使用正则表达式解析查询参数

javascript - 点击链接时的点击计数器 PHP/JS

visual-studio - 在 Chrome 中运行的 Angular 4 应用程序的 Visual Studio 2017 中的选择控件上不会触发更改和 ngModelChange

html - 运行 ng build 时,index.html 什么都不做?

css - 如何从父组件的 CSS 文件中设置子组件的样式?