Skip to content

Commit

Permalink
Merge pull request #6 from dkhrunov/development
Browse files Browse the repository at this point in the history
Version 2.0.0
  • Loading branch information
dkhrunov authored Aug 5, 2022
2 parents 98210d4 + b11cfe7 commit a62e143
Show file tree
Hide file tree
Showing 26 changed files with 4,512 additions and 3,822 deletions.
63 changes: 48 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ This library is configurable for any use cases.
</a>

## Other languages
- [Russian](./doc/ru/README.md)
- [Russian](../../doc/ru/README.md)

## Version Compliance
Angular version | 13 |
--- | --- |
ngx-jwt-auth version | 1 |
Angular version | 13 | 14 |
--- | --- | ---|
ngx-jwt-auth version | 1 | 2 |

## Content
- [Description](#description)
Expand All @@ -23,6 +23,7 @@ ngx-jwt-auth version | 1 |
- [List of predefined Token Storages](#list-of-predefined-token-storages)
- [Creating your own Token Storage](#creating-your-own-token-storage)
- [Changing token storage at runtime](#changing-token-storage-at-runtime)
- [Creating your own LastPageWatcher](#creating-your-own-lastpagewatcher)
- [Troubleshooting](#troubleshooting)

## Description
Expand All @@ -33,13 +34,13 @@ Features:
- choose where tokens will be stored by choosing a token storage;
- change the storage of tokens directly in runtime;
- create your own custom storage of tokens;
- automatically refresh the access token. Refresh occurs either after the validity period of the access token expires, or specify the `refreshThreshold` token decay coefficient, upon reaching which the token will be updated, for these purposes the interceptor [JwtAuthInterceptor](./projects/ngx-jwt-auth/src/lib/interceptors/jwt-auth.interceptor.ts) is used.
- restrict access to certain routes for unauthorized users using [AuthGuard](./projects/ngx-jwt-auth/src/lib/guards/auth.guard.ts);
- restrict access to certain routes for authorized users using [UnAuthGuard](./projects/ngx-jwt-auth/src/lib/guards/un-auth.guard.ts);
- subscribe to the `isLoggedIn$` stream, which stores the current user authentication status [JwtAuthService](./projects/ngx-jwt-auth/src/lib/services/jwt-auth.service.ts);
- manage tokens yourself (get, delete, save a token) through the service [AuthTokenManager](./projects/ngx-jwt-auth/src/lib/services/auth-token-manager.service.ts);
- manage not only authorization tokens, but any other JWT tokens for these purposes, there are separate settings in `JwtAuthModule`, a separate token storage (you can use the same predefined storages, or create your own), a separate service for working with tokens [TokenManager] (. /src/lib/services/token-manager.service.ts) and a separate service for managing token storage [TokenStorageManager](./projects/ngx-jwt-auth/src/lib/services/token-storage-manager.service.ts).
- extend the basic features by creating custom token stores, custom token management solutions (extend [BaseTokenManager](./projects/ngx-jwt-auth/src/lib/services/base-token-manager.ts)) and token stores (extend [BaseTokenStorageManager](./projects/ngx-jwt-auth/src /lib/services/base-token-storage-manager.ts)).
- automatically refresh the access token. Refresh occurs either after the validity period of the access token expires, or specify the `refreshThreshold` token decay coefficient, upon reaching which the token will be updated, for these purposes the interceptor [JwtAuthInterceptor](./src/lib/interceptors/jwt-auth.interceptor.ts) is used.
- restrict access to certain routes for unauthorized users using [AuthGuard](./src/lib/guards/auth.guard.ts);
- restrict access to certain routes for authorized users using [UnAuthGuard](./src/lib/guards/un-auth.guard.ts);
- subscribe to the `isLoggedIn$` stream, which stores the current user authentication status [JwtAuthService](./src/lib/services/jwt-auth.service.ts);
- manage tokens yourself (get, delete, save a token) through the service [AuthTokenManager](./src/lib/services/auth-token-manager.service.ts);
- manage not only authorization tokens, but any other JWT tokens for these purposes, there are separate settings in `JwtAuthModule`, a separate token storage (you can use the same predefined storages, or create your own), a separate service for working with tokens [TokenManager] (. /src/lib/services/token-manager.service.ts) and a separate service for managing token storage [TokenStorageManager](./src/lib/services/token-storage-manager.service.ts).
- extend the basic features by creating custom token stores, custom token management solutions (extend [BaseTokenManager](./src/lib/services/base-token-manager.ts)) and token stores (extend [BaseTokenStorageManager](./src /lib/services/base-token-storage-manager.ts)).

## Setup and use
1. Import `JwtAuthModule` into the App/Core module of your application with a call to the `forRoot` method, and pass parameters to this method:
Expand All @@ -56,7 +57,7 @@ import { JwtAuthModule } from '@dekh/ngx-jwt-auth';
export class AppModule {}
```

2. Next, you must to create an Api-service by implementing the [BaseAuthApiService](./projects/ngx-jwt-auth/src/lib/services/base-auth-api-service.ts) base class. This class obliges to implement 3 methods `login`, `logout` and `refresh`. The `login` and `refresh` methods must return an Observable with the value `{ accessToken: string; refreshToken?: string; }`, if your server in the `login` authorization method and\or in the `refresh` access token refresh method returns a different format, then it is quite easy to map the value with the `map` operator from rxjs to the desired format. An example of such a service:
2. Next, you must to create an Api-service by implementing the [BaseAuthApiService](./src/lib/services/base-auth-api-service.ts) base class. This class obliges to implement 3 methods `login`, `logout` and `refresh`. The `login` and `refresh` methods must return an Observable with the value `{ accessToken: string; refreshToken?: string; }`, if your server in the `login` authorization method and\or in the `refresh` access token refresh method returns a different format, then it is quite easy to map the value with the `map` operator from rxjs to the desired format. An example of such a service:

```typescript
import { Injectable } from '@angular/core';
Expand Down Expand Up @@ -141,7 +142,7 @@ import { AuthApiService } from './auth/services/auth-api.service';
export class AppModule {}
```

4. Provide Interceptor [JwtAuthInterceptor](./projects/ngx-jwt-auth/src/lib/interceptors/jwt-auth.interceptor.ts).
4. Provide Interceptor [JwtAuthInterceptor](./src/lib/interceptors/jwt-auth.interceptor.ts).

> `JwtAuthInterceptor` implements an access token refresh mechanism by checking the validity of the token and the `refreshTreshold` validity threshold before each request, except for requests whose URL is specified in the `unsecuredUrls` parameter. If the token is not valid, then an attempt will be made to refresh the token followed by the original request, but if the token cannot be refreshed, then the user will be logged out using the `logout` method from `BaseAuthApiService`.
Expand Down Expand Up @@ -331,6 +332,9 @@ export class AppRoutingModule {}

- `authGuardRedirectUrl?: string` - The URL where an unauthorized user will be redirected to if they try to access a route protected by AuthGuard. If not set, then routes protected by AuthGuard will simply reject the transition to this route.

- `redirectToLastPage?: boolean | Type<BaseLastPageWatcher>` - Redirects the user to the last visited page after authorization. By default `false`.
> If you set the value of `Type<BaseLastPageWatcher>` then your provider will be used. On the other hand, if you set it to `true`, the default `LastPageWatcher` will be used.
## List of predefined Token Storages

- `CookiesTokenStorage` - abstraction over cookies, saves tokens in cookies;
Expand All @@ -340,7 +344,7 @@ export class AppRoutingModule {}

## Creating your own Token Storage

In order to create your own token storage, it is enough to implement the [BaseTokenStorage](./projects/ngx-jwt-auth/src/lib/token-storages/base-token-storage.ts) base class and specify an array of custom storage of tokens. Example:
In order to create your own token storage, it is enough to implement the [BaseTokenStorage](./src/lib/token-storages/base-token-storage.ts) base class and specify an array of custom storage of tokens. Example:

```typescript
// my-custom-token-storage.ts
Expand Down Expand Up @@ -429,7 +433,7 @@ export class AppModule {

## Changing token storage at runtime

In rare cases, you may need to change the token storage at runtime, for this there are two services [TokenStorageManager](./projects/ngx-jwt-auth/src/lib/services/token-storage-manager.service.ts) and [AuthTokenStorageManager](./projects/ngx-jwt-auth/src/lib/services /auth-token-storage-manager.service.ts), both of these services implements the same interface. `TokenStorageManager` is used to manage the storage of __simple/non-authorization__ tokens, and `AuthTokenStorageManager` is used to manage the storage of __authorization__ tokens.
In rare cases, you may need to change the token storage at runtime, for this there are two services [TokenStorageManager](./src/lib/services/token-storage-manager.service.ts) and [AuthTokenStorageManager](./src/lib/services /auth-token-storage-manager.service.ts), both of these services implements the same interface. `TokenStorageManager` is used to manage the storage of __simple/non-authorization__ tokens, and `AuthTokenStorageManager` is used to manage the storage of __authorization__ tokens.

Пример:

Expand Down Expand Up @@ -484,6 +488,35 @@ export class TokenStorageChangerService {
}
```

## Creating your own LastPageWatcher

1. Create a custom service to track page changes:
```typescript
@Injectable()
export class CustomLastPageWatcher extends BaseLastPageWatcher {

constructor() {
this.watch();
}

public savePath(path: string): void {
// logic to save path, e.g send to server to save it in DB
}

public getPath(): string | null {
// logic to get path, e.g from server
}
}
```

2. Specify your class in the settings:
```typescript
JwtAuthModule.forRoot({
[...],
redirectToLastPage: CustomLastPageWatcher
})
```

## Troubleshooting

- When starting the application, it gives an error __"ERROR Error: NG0200: Circular dependency in DI detected for JwtAuthService."__
Expand Down
4 changes: 3 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,7 @@
}
}
},
"defaultProject": "ngx-jwt-auth"
"cli": {
"analytics": false
}
}
39 changes: 36 additions & 3 deletions doc/ru/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
</a>

## Соответствие версий
Angular version | 13 |
--- | --- |
ngx-jwt-auth version | 1 |
Angular version | 13 | 14 |
--- | --- | ---|
ngx-jwt-auth version | 1 | 2 |

## Содержание
- [Описание](#описание)
Expand All @@ -20,6 +20,7 @@ ngx-jwt-auth version | 1 |
- [Список предопределенных хранилищ токенов](#список-предопределенных-хранилищ-токенов)
- [Создание своего хранилища токенов](#создание-своего-хранилища-токенов)
- [Смена хранилища токенов в рантайме](#смена-хранилища-токенов-в-рантайме)
- [Реализация кастомной стратегии сохранения последней посещенной страницы](#реализация-кастомной-стратегии-сохранения-последней-посещенной-страницы)
- [Troubleshooting](#troubleshooting)

## Описание
Expand Down Expand Up @@ -329,6 +330,9 @@ export class AppRoutingModule {}

- `authGuardRedirectUrl?: string` - URL куда будет редиректить не авторизованного пользователя, если он попробует зайти на route защищенный AuthGuard. Если не задать значение, то route защищенный AuthGuard будут просто отклонять переход на данный route.

- `redirectToLastPage?: boolean | Type<BaseLastPageWatcher>` - Перенаправляет пользователя на последнюю посещенную страницу после авторизации. By default `false`.
> Если вы установите значение `Type<BaseLastPageWatcher>`, тогда будет использоваться ваш провайдер. С другой стороны, если вы установите значение `true`, тогда будет использоваться стандартный `LastPageWatcher`.
## Список предопределенных хранилищ токенов

- `CookiesTokenStorage` - абстракция над cookies, сохраняет токены в cookies;
Expand Down Expand Up @@ -482,6 +486,35 @@ export class TokenStorageChangerService {
}
```

## Реализация кастомной стратегии сохранения последней посещенной страницы

1. Создать кастомный сервис для отслеживания изменения страниц:
```typescript
@Injectable()
export class CustomLastPageWatcher extends BaseLastPageWatcher {

constructor() {
this.watch();
}

public savePath(path: string): void {
// logic to save path, e.g send to server to save it in DB
}

public getPath(): string | null {
// logic to get path, e.g from server
}
}
```

2. Указать свой класс в настройках:
```typescript
JwtAuthModule.forRoot({
[...],
redirectToLastPage: CustomLastPageWatcher
})
```

## Troubleshooting

- При старте приложения выдает ошибку __"ERROR Error: NG0200: Circular dependency in DI detected for JwtAuthService."__
Expand Down
Loading

0 comments on commit a62e143

Please sign in to comment.