NativeScript Angular JWT
Angular 的 JSON Web Token 辅助库
npm i --save nativescript-angular-jwt

NativeScript Angular JWT

npm version

注意:此库现在版本为 5,并在 npm 上作为 nativescript-angular-jwt 发布。如果您正在寻找此库的 v1.0.9 之前的版本,可以在 pre-v1.0 分支和 npm 上作为 angular2-jwt 找到。

此库的 v5 版本对 allowedDomainsdisallowedRoutes 有一些破坏性更改。

NativeScript Angular JWT v5 应与 Angular v10+ 和 RxJS v6+ 一起使用。对于 Angular v6+ 到 v9,请使用 nativescript-angular-jwt v4

此库提供了一个 HttpInterceptor,它将自动将 JSON Web Token 添加到 HttpClient 请求中。

此库不提供任何实现用户身份验证或检索 JWT 的功能。这些细节将根据您的设置而有所不同,但在大多数情况下,您将使用常规 HTTP 请求来验证用户,并在成功后将其 JWT 存储在本地存储或 cookie 中。

注意:此库只能与 Angular 4.3 及更高版本一起使用,因为它依赖于 Angular 的 HttpClientHttpInterceptor。此功能在较低版本中不可用。

安装

# installation with npm
npm install nativescript-angular-jwt

# installation with yarn
yarn add nativescript-angular-jwt

用法:独立

如果您只对 JWT 解码器感兴趣,并且不感兴趣于扩展的可注入功能,您可以简单地创建一个实用工具实例并直接使用它

import { JwtHelperService } from "nativescript-angular-jwt";

const helper = new JwtHelperService();

const decodedToken = helper.decodeToken(myRawToken);
const expirationDate = helper.getTokenExpirationDate(myRawToken);
const isExpired = helper.isTokenExpired(myRawToken);

用法:注入

导入 JwtModule 模块并将其添加到您的导入列表中。调用 forRoot 方法并提供一个 tokenGetter 函数。您还必须将任何域添加到 allowedDomains 中,您想要通过指定一个 allowedDomains 数组来对其实施请求。

务必导入 HttpClientModule

import { JwtModule } from "nativescript-angular-jwt";
import { HttpClientModule } from "@angular/common/http";

export function tokenGetter() {
return localStorage.getItem("access_token");
}

@NgModule({
bootstrap: [AppComponent],
imports: [
// ...
HttpClientModule,
JwtModule.forRoot({
config: {
tokenGetter: tokenGetter,
allowedDomains: ["example.com"],
disallowedRoutes: ["http://example.com/examplebadroute/"],
},
}),
],
})
export class AppModule {}

使用 Angular 的 HttpClient 发送的任何请求都将自动附加一个作为 Authorization 标头的 token。

import { HttpClient } from "@angular/common/http";

export class AppComponent {
constructor(public http: HttpClient) {}

ping() {
this.http.get("http://example.com/api/things").subscribe(
(data) => console.log(data),
(err) => console.log(err)
);
}
}

配置选项

tokenGetter: function(HttpRequest): string

tokenGetter 是一个函数,它返回用户的 token。此函数只需调用存储 token 的位置进行检索调用。在许多情况下,token 将存储在本地存储或会话存储中。

// ...
JwtModule.forRoot({
config: {
// ...
tokenGetter: () => {
return localStorage.getItem("access_token");
},
},
});

如果您为多个域有多个 token,可以使用传递给 tokenGetter 函数的 HttpRequest 来获取每个拦截请求的正确 token。

// ...
JwtModule.forRoot({
config: {
// ...
tokenGetter: (request) => {
if (request.url.includes("foo")) {
return localStorage.getItem("access_token_foo");
}

return localStorage.getItem("access_token");
},
},
});

allowedDomains: array

应仅向您知道和信任的域发送经过身份验证的请求。许多应用程序从多个域请求 API,其中一些域不由开发人员控制。由于无法知道被调用的 API 将如何处理请求中包含的信息,因此最好不要将用户的 token 以盲目的方式发送到所有 API。

指定要允许发送经过身份验证的请求的域,请在 allowedDomains 数组中指定它们。注意,标准 http 端口 80 和 https 端口 443 请求不需要指定端口号。如果是在非标准端口上身份验证,例如 localhost:3001,则需要指定端口号。

// ...
JwtModule.forRoot({
config: {
// ...
allowedDomains: ["localhost:3001", "foo.com", "bar.com"],
},
});

disallowedRoutes: array

如果您不希望替换特定路由的授权头,请在此处列出。如果在初始授权路由位于允许的域并且使用基本授权头的情况下,这会很有用。这些路由需要使用正确的协议(http://https://)进行前缀。如果您想在不考虑协议的情况下将路由添加到不允许的路由列表中,可以在其前面加上//

// ...
JwtModule.forRoot({
config: {
// ...
disallowedRoutes: [
"http://localhost:3001/auth/",
"https://foo.com/bar/",
"//foo.com/bar/baz",
/localhost:3001\/foo\/far.*/,
], // strings and regular expressions
},
});

注意:如果请求发送到提供您的Angular应用程序的同一域名,则不需要将该域名添加到allowedDomains数组中。但是,这只在您没有在Http请求中指定域名的情况下适用。

例如,以下请求假设域名与提供您应用程序的域名相同。在这种情况下,不需要允许。

this.http.get('/api/things')
.subscribe(...)

然而,如果您正在同一域名上提供您的API,并且您在Http请求中指定了该域名,那么它就需要明确允许。

// Both the Angular app and the API are served at
// localhost:4200 but because that domain is specified
// in the request, it must be allowed
this.http.get('http://localhost:4200/api/things')
.subscribe(...)

headerName: string

默认的头部名称是Authorization。可以通过指定一个自定义的headerName来更改它,该值应该是一个字符串。

// ...
JwtModule.forRoot({
config: {
// ...
headerName: "Your Header Name",
},
});

authScheme: string | function(HttpRequest): string

默认的授权方案是Bearer后跟一个空格。可以通过指定自定义的authScheme来更改它。您可以通过传递一个字符串来为每个请求添加令牌前缀。

// ...
JwtModule.forRoot({
config: {
// ...
authScheme: "Basic ",
},
});

如果您想动态更改或基于请求更改授权方案,可以配置一个返回字符串的getter函数。

// ...
JwtModule.forRoot({
config: {
// ...
authScheme: (request) => {
if (request.url.includes("foo")) {
return "Basic ";
}

return "Bearer ";
},
},
});

throwNoTokenError: boolean

throwNoTokenError设置为true将在使用tokenGetter函数无法检索令牌时引发错误。默认为false

// ...
JwtModule.forRoot({
config: {
// ...
throwNoTokenError: true,
},
});

skipWhenExpired: boolean

默认情况下,即使JWT已过期,用户的JWT也将发送到HttpClient请求中。您可以选择通过将skipWhenExpired设置为true来不允许发送已过期的令牌。

// ...
JwtModule.forRoot({
config: {
// ...
skipWhenExpired: true,
},
});

使用自定义选项工厂函数

在某些情况下,您可能需要提供一个自定义工厂函数来正确处理您的配置选项。如果您的tokenGetter函数依赖于服务或您正在使用异步存储机制(如Ionic的Storage),则情况就是这样。

导入JWT_OPTIONS InjectionToken,以便您可以指示它使用您的自定义工厂函数。

创建一个工厂函数,并指定选项,就像您直接使用JwtModule.forRoot一样。如果您需要在函数中使用服务,请将其作为参数列出,并在提供函数时将其传递到deps数组中。

import { JwtModule, JWT_OPTIONS } from 'nativescript-angular-jwt';
import { TokenService } from './app.tokenservice';

// ...

export function jwtOptionsFactory(tokenService) {
return {
tokenGetter: () => {
return tokenService.getAsyncToken();
},
allowedDomains: ["example.com"]
}
}

// ...

@NgModule({
// ...
imports: [
JwtModule.forRoot({
jwtOptionsProvider: {
provide: JWT_OPTIONS,
useFactory: jwtOptionsFactory,
deps: [TokenService]
}
})
],
providers: [TokenService]
})

注意:如果定义了jwtOptionsFactory,则忽略config两种配置选项不能同时定义

Ionic 2+的配置

上述自定义工厂函数方法可以用于使用Ionic的Storage异步获取令牌。

import { JwtModule, JWT_OPTIONS } from 'nativescript-angular-jwt';
import { Storage } from '@ionic/storage';

export function jwtOptionsFactory(storage) {
return {
tokenGetter: () => {
return storage.get('access_token');
},
allowedDomains: ["example.com"]
}
}

// ...

@NgModule({
// ...
imports: [
JwtModule.forRoot({
jwtOptionsProvider: {
provide: JWT_OPTIONS,
useFactory: jwtOptionsFactory,
deps: [Storage]
}
})
]
})

注意:如果定义了jwtOptionsFactory,则忽略config两种配置选项不能同时定义

配置选项

JwtHelperService: 服务

此服务包含辅助函数

isTokenExpired(旧的tokenNotExpired函数)

import { JwtHelperService } from 'nativescript-angular-jwt';
// ...
constructor(public jwtHelper: JwtHelperService) {}

ngOnInit() {
console.log(this.jwtHelper.isTokenExpired()); // true or false
}

getTokenExpirationDate

import { JwtHelperService } from 'nativescript-angular-jwt';
// ...
constructor(public jwtHelper: JwtHelperService) {}

ngOnInit() {
console.log(this.jwtHelper.getTokenExpirationDate()); // date
}

decodeToken

import { JwtHelperService } from 'nativescript-angular-jwt';
// ...
constructor(public jwtHelper: JwtHelperService) {}

ngOnInit() {
console.log(this.jwtHelper.decodeToken(token)); // token
}

什么是Auth0?

Auth0帮助您

  • 添加多种身份验证源的身份验证,无论是社交网络(如Google、Facebook、Microsoft Account、LinkedIn、GitHub、Twitter、Box、Salesforce等)还是企业身份系统(如Windows Azure AD、Google Apps、Active Directory、ADFS或任何SAML身份提供者)。
  • 通过更传统的用户名/密码数据库添加身份验证。
  • 支持将不同的用户账户与同一用户关联
  • 支持生成带签名的JSON Web Tokens,以安全地调用API和流式传输用户身份
  • 分析用户登录的时间、地点和方式。
  • 通过JavaScript规则从其他来源拉取数据并添加到用户资料中。

创建免费的Auth0账户

  1. 前往Auth0并点击注册。
  2. 使用Google、GitHub或Microsoft账户登录。

问题报告

如果您发现了一个bug或有功能请求,请在此存储库的问题部分报告它们。请不要在公共GitHub问题跟踪器上报告安全漏洞。有关披露安全问题的程序,请参阅负责任披露计划

作者

Auth0

许可证

本项目采用MIT许可证。有关更多信息,请参阅LICENSE文件。