Angular 如何在模块级别访问 SharedService 5+
How to access a SharedService at Module level in Angular 5+
我对 Angular5/TypeScript 比较陌生,所以对于这个(可能)微不足道的问题,我深表歉意。
我正在尝试实现我打算使用的身份验证服务,以便让我的 Angular5 前端使用 wordpress 后端公开的一些 REST API。
到目前为止,该服务已实施并正常运行。我现在缺少的是一种将登录数据注入 REST 请求的方法。
更准确地说,我知道该怎么做,但我现在不知道如何访问我之前存储在我的共享服务中的登录信息。
但让我更具体一点,让我分享我的代码:
// auth.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
import { JwtHelperService } from '@auth0/angular-jwt';
interface IUser
{
token: string,
token_expires: number,
user_display_name: string,
}
@Injectable()
export class AuthService
{
private currentUser: IUser = null;
private nonce: string = '';
constructor(
private http: HttpClient,
private jwt: JwtHelperService,
)
{
// set User Info if saved in local/session storage
.
.
.
}
logIn(username: string, password: string, persist: boolean): Observable<boolean>
{
return this.http.post(
API_BASE_DOMAIN + API_BASE_PATH + '/jwt-auth/v1/token',
{ username: username, password: password },
{
observe: 'response', // Full response instead of the body only
withCredentials: true, // Send cookies
}
).map(response => {
this.nonce = response.headers.get('X-WP-Nonce');
const body: any = response.body
// login successful if there's a jwt token in the response
if (body.token)
{
// set current user data
this.currentUser = <IUser>body;
// store username and jwt token in local storage to keep user logged in between page refreshes
let storage = (persist) ? localStorage : sessionStorage;
storage.setItem('currentUser', JSON.stringify(this.currentUser));
// return true to indicate successful login
return true;
}
else
{
// return false to indicate failed login
return false;
}
});
}
getNonce(): string
{
console.log((this.nonce) ? this.nonce : '');
return (this.nonce) ? this.nonce : '';
}
getToken(): string
{
console.log((this.currentUser) ? this.currentUser.token : '');
return (this.currentUser) ? this.currentUser.token : '';
}
}
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { JwtModule } from '@auth0/angular-jwt';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { AuthService } from './main/auth/services/auth.service';
import { AuthGuardService } from './main/auth/services/auth-guard.service';
import { API_BASE_DOMAIN } from './main/auth/services/auth.service';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { NonceHttpInterceptor } from './main/auth/auth.interceptor';
const appRoutes: Routes = [
.
.
.
];
@NgModule({
declarations: [
AppComponent
],
imports : [
BrowserModule,
HttpClientModule,
RouterModule.forRoot(appRoutes),
// Jwt Token Injection
JwtModule.forRoot({
config: {
tokenGetter: (***AuthService?????***).getToken,
whitelistedDomains: [ API_BASE_DOMAIN ]
}
})
],
providers : [
AuthService,
AuthGuardService,
{
provide: HTTP_INTERCEPTORS,
useClass: NonceHttpInterceptor,
multi: true
}
],
bootstrap : [
AppComponent
]
})
export class AppModule
{
}
正如您在我的代码中看到的 //JWT 令牌注入,我需要指定一个令牌 getter,它在我的 auth.service.
中实现
在组件文件中,我可以通过将服务作为构造函数的参数注入来访问其 public 方法,如下所示:
//login.component.ts
import { AuthService } from '../services/auth.service';
@Component({
.
.
.
})
export class MyLoginComponent implements OnInit
{
constructor(
private authService: AuthService,
)
{
.
.
.
}
onFormSubmit()
{
this.authService.logIn(uname, pwd, persist)
.subscribe(
.
.
.
);
}
}
但我似乎找不到在模块级别访问服务方法的方法!
我知道,我可以对我的 tokenGetter 使用静态访问并将所有内容移动到 class 级别而不是实例级别(像这样:AuthService.getToken
),但我认为有更好、更优雅的方法访问 getToken()
方法的方法。
提前感谢您的任何 hint/help。
Angular2-jwt 支持使用 custom options factory function,用于特定情况,例如
tokenGetter function relies on a service
像这样定义工厂函数
export function jwtOptionsFactory(authService: AuthService) {
return {
tokenGetter: () => {return authService.getToken();},
whitelistedDomains: [ API_BASE_DOMAIN ]
}
}
然后将该函数声明为 JWT_OPTIONS
令牌
的工厂
imports: [
JwtModule.forRoot({
jwtOptionsProvider: {
provide: JWT_OPTIONS,
useFactory: jwtOptionsFactory,
deps: [AuthService]
}
})
],
NOTE: If a jwtOptionsFactory is defined, then config is ignored. Both configuration alternatives can't be defined at the same time.
我对 Angular5/TypeScript 比较陌生,所以对于这个(可能)微不足道的问题,我深表歉意。
我正在尝试实现我打算使用的身份验证服务,以便让我的 Angular5 前端使用 wordpress 后端公开的一些 REST API。
到目前为止,该服务已实施并正常运行。我现在缺少的是一种将登录数据注入 REST 请求的方法。
更准确地说,我知道该怎么做,但我现在不知道如何访问我之前存储在我的共享服务中的登录信息。
但让我更具体一点,让我分享我的代码:
// auth.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
import { JwtHelperService } from '@auth0/angular-jwt';
interface IUser
{
token: string,
token_expires: number,
user_display_name: string,
}
@Injectable()
export class AuthService
{
private currentUser: IUser = null;
private nonce: string = '';
constructor(
private http: HttpClient,
private jwt: JwtHelperService,
)
{
// set User Info if saved in local/session storage
.
.
.
}
logIn(username: string, password: string, persist: boolean): Observable<boolean>
{
return this.http.post(
API_BASE_DOMAIN + API_BASE_PATH + '/jwt-auth/v1/token',
{ username: username, password: password },
{
observe: 'response', // Full response instead of the body only
withCredentials: true, // Send cookies
}
).map(response => {
this.nonce = response.headers.get('X-WP-Nonce');
const body: any = response.body
// login successful if there's a jwt token in the response
if (body.token)
{
// set current user data
this.currentUser = <IUser>body;
// store username and jwt token in local storage to keep user logged in between page refreshes
let storage = (persist) ? localStorage : sessionStorage;
storage.setItem('currentUser', JSON.stringify(this.currentUser));
// return true to indicate successful login
return true;
}
else
{
// return false to indicate failed login
return false;
}
});
}
getNonce(): string
{
console.log((this.nonce) ? this.nonce : '');
return (this.nonce) ? this.nonce : '';
}
getToken(): string
{
console.log((this.currentUser) ? this.currentUser.token : '');
return (this.currentUser) ? this.currentUser.token : '';
}
}
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { JwtModule } from '@auth0/angular-jwt';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { AuthService } from './main/auth/services/auth.service';
import { AuthGuardService } from './main/auth/services/auth-guard.service';
import { API_BASE_DOMAIN } from './main/auth/services/auth.service';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { NonceHttpInterceptor } from './main/auth/auth.interceptor';
const appRoutes: Routes = [
.
.
.
];
@NgModule({
declarations: [
AppComponent
],
imports : [
BrowserModule,
HttpClientModule,
RouterModule.forRoot(appRoutes),
// Jwt Token Injection
JwtModule.forRoot({
config: {
tokenGetter: (***AuthService?????***).getToken,
whitelistedDomains: [ API_BASE_DOMAIN ]
}
})
],
providers : [
AuthService,
AuthGuardService,
{
provide: HTTP_INTERCEPTORS,
useClass: NonceHttpInterceptor,
multi: true
}
],
bootstrap : [
AppComponent
]
})
export class AppModule
{
}
正如您在我的代码中看到的 //JWT 令牌注入,我需要指定一个令牌 getter,它在我的 auth.service.
中实现在组件文件中,我可以通过将服务作为构造函数的参数注入来访问其 public 方法,如下所示:
//login.component.ts
import { AuthService } from '../services/auth.service';
@Component({
.
.
.
})
export class MyLoginComponent implements OnInit
{
constructor(
private authService: AuthService,
)
{
.
.
.
}
onFormSubmit()
{
this.authService.logIn(uname, pwd, persist)
.subscribe(
.
.
.
);
}
}
但我似乎找不到在模块级别访问服务方法的方法!
我知道,我可以对我的 tokenGetter 使用静态访问并将所有内容移动到 class 级别而不是实例级别(像这样:AuthService.getToken
),但我认为有更好、更优雅的方法访问 getToken()
方法的方法。
提前感谢您的任何 hint/help。
Angular2-jwt 支持使用 custom options factory function,用于特定情况,例如
tokenGetter function relies on a service
像这样定义工厂函数
export function jwtOptionsFactory(authService: AuthService) {
return {
tokenGetter: () => {return authService.getToken();},
whitelistedDomains: [ API_BASE_DOMAIN ]
}
}
然后将该函数声明为 JWT_OPTIONS
令牌
imports: [
JwtModule.forRoot({
jwtOptionsProvider: {
provide: JWT_OPTIONS,
useFactory: jwtOptionsFactory,
deps: [AuthService]
}
})
],
NOTE: If a jwtOptionsFactory is defined, then config is ignored. Both configuration alternatives can't be defined at the same time.