Options
All
  • Public
  • Public/Protected
  • All
Menu

Module ngx-customapp-jwt

Install package and it's dependencies.

yarn add @ngrx/store @ngrx/effects ngx-customapp-jwt

Create the config JwtConfig. You can read recommendations in the description of each field.

Here is an example of the JwtApi implementation.

@Injectable({
providedIn: 'root'
})
export class JwtApiService implements JwtApi<UserCredentials, AuthResponse.AsObject> {

constructor(
// provided by ngx-customapp-proto-http package. Handles serialization, deserialization and errors.
private request: RequestService<api.Request.AsObject, api.Response.AsObject>
) {
}

login(credentials: UserCredentials): Observable<AuthResponse.AsObject> {
const req = {
id: 0,
auth: userCredentialsToAuthRequest(credentials),
}
console.log('request', req)
return this.request.request(
authEndpoint,
req,
undefined, // no headers
true // disable jwt interceptor
).pipe(
map(response => response.auth!)
)
}

logout(accessToken: TokenInfo.AsObject, fromAllDevices: boolean | undefined): Observable<void> {
return this.request.request(
fromAllDevices ? fullLogoutEndpoint : logoutEndpoint,
undefined, // no request body
new HttpHeaders().set(authHeader.name, authHeader.createValue(accessToken)), // add access token to the header
true // disable jwt interceptor
).pipe(
map(() => void 0)
)
}

refresh(refreshToken: TokenInfo.AsObject): Observable<TokenResponse.AsObject> {
return this.request.request(
tokenRefreshEndpoint,
undefined, // no request body
new HttpHeaders().set(authHeader.name, authHeader.createValue(refreshToken)), // add refresh token to the header
true, // disable jwt interceptor
).pipe(
map(response => response.tokens!)
)
}
}

This package plugs to the application NgRx store as a separate substore.

Import JwtModule.forRoot(jwtConfig) in your app. This will enable ngx-customapp-jwt store and provide services.

Add types to the NgRx AppState.

import {jwtFeatureKey, JwtRootState} from 'ngx-customapp-jwt';
import {UserInfo} from './user-info';

export interface AppState {
// ... other fields of your state
[jwtFeatureKey]: JwtRootState<UserInfo>
}

Use jwtActions() function to create actions. Use created actions in your app.

export const {
login,
loginSucceed,
loginErrored,

logout,
logoutSucceed,
logoutErrored,
} = jwtActions<UserCredentials, AuthResponse.AsObject, UserInfo>()

Use jwtSelectors() function to create selectors. Use created selectors in your app.

export const {
selectJwtUser,
selectJwtLoginInProcess,
selectJwtLogoutInProcess
} = jwtSelectors<UserInfo>()

Dispatch login({credentials}) to log in.

this.store.dispatch(
login({
credentials: {
authType: UserAuthType.logPass,
login: userLogin,
passHash
}
})
)

Dispatch logout({fromAllDevices}) to log out.

this.store.dispatch(
logout({fromAllDevices: false})
);

Handle the navigation after logging in.

@Injectable()
export class AuthEffects {
navIntoApp$ = createEffect(() => this.actions$.pipe(
ofType(loginSucceed),
tap(() => {
this.router.navigate([appMainPage]);
})
), {dispatch: false})
}

Handle the navigation after logging out.

@Injectable()
export class AuthEffects {
navIntoApp$ = createEffect(() => this.actions$.pipe(
ofType(logoutSucceed),
tap(() => {
this.router.navigate([appAuthPage]);
})
), {dispatch: false})
}

Display errors.

@Injectable()
export class AuthEffects {
showError$ = createEffect(() => this.actions$.pipe(
ofType(loginErrored, logoutErrored),
tap(({error}) => {
// error returned by JwtApi.login or JwtApi.logout functions.
this.notifyService.displayError(error);
})
), {dispatch: false})
}

Add JwtInterceptor to the app.module providers, and every request will be sent with JWT in the header.

import {JwtInterceptor} from 'ngx-customapp-jwt'

@NgModule({
// ... imports, declarations, bootstrap
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: JwtInterceptor,
multi: true,
}
]
})
export class AppModule {
}

If you have configured JwtConfig.jwtGuard, add the JwtGuard to the routing, to handle paths, that require the user to be authorized.

{
path: 'main',
component: UiShellComponent,
canActivate: [JwtGuard],
children: [
// ... child paths
]
},

You can also listen for the result of the authorization, triggered by the JwtGuard.

@Injectable()
export class AuthEffects {
showError$ = createEffect(() => this.actions$.pipe(
ofType(loginAgainSucceed, loginAgainErrored),
tap(action => {
// do something with the auth response or the error.
})
), {dispatch: false})
}

Index

Variables

JWT_ACTIONS: InjectionToken<JwtActions<any, any, any, any>> = ...
JWT_CONFIG: InjectionToken<JwtConfig<any, any, any, any>> = ...
JWT_SELECTORS: InjectionToken<JwtSelectors<any>> = ...
defaultJwtStorageKey: "userTokenStorage" = 'userTokenStorage'
disableJwtInterception: HttpContextToken<boolean> = ...
jwtFeatureKey: "ngx-customapp-jwt" = packageName
metaReducers: MetaReducer<JwtRootState<any>>[] = []
reducers: ActionReducerMap<JwtRootState<any>> = ...

Functions

  • jwtActions<Credentials, AuthResponse, UserInfo, UserId>(): JwtActions<Credentials, AuthResponse, UserInfo, UserId>
  • Actions of the JWT store.

    login - to be dispatched from login page (or, may be, login effects, if you have complex authorization)

    loginSucceed, loginErrored - to indicate the result of the authorization.

    loginAgain - internal, is dispatched from the JwtGuard. Mostly the same, as login, but can have different effects (e.g. no navigation after loginAgainSucceed).

    loginAgainSucceed, loginAgainErrored - to indicate the result of the authorization, triggered by the loginAgain action.

    loginAs - to be dispatched by the authorized user, who wants to log in as another user. Contains the target user's UserId.

    loginAsSucceed, loginAsErrored - to indicate the result of the authorization as another user.

    logout - to be dispatched by the authorized user. If there have been dispatched loginAs before, JWTs of the current user are destroyed (via calling JwtApi.logout), and JWTs and the UserInfo of the previous user are restored from the store.

    logoutSucceed, logoutErrored - to indicate the result of the logout.

    stashUser, unstashUser, setUser - internal, are used to implement restoration of the previous user (if there have been dispatched loginAs) during logout.

    Type Parameters

    • Credentials

    • AuthResponse

    • UserInfo

    • UserId = number

    Returns JwtActions<Credentials, AuthResponse, UserInfo, UserId>

Generated using TypeDoc