@lcgroup.core/auth
AuthModule allows to add authentication/authorization mechanism (based on security token service) to your project.
Features
- JWT integration
- Custom user support
- Extensibility auth logic (Custom auth service support)
- Available two ways of token storage - via localstorage (by default) or cookie
Setup
AuthModule works in pair with JwtModule.
Setup example:
export function jwtOptionsFactory(authTokenService: AuthTokenService) {
return {
tokenGetter: () => {
return authTokenService.getToken();
},
allowedDomains: environment.allowedDomains
};
}
JwtModule.forRoot({
jwtOptionsProvider: {
provide: JWT_OPTIONS,
useFactory: jwtOptionsFactory,
deps: [AuthTokenService]
}
}),
AuthModule.forRoot({
stsParams: {
client_id: 'your_client_id',
client_secret: 'some_secret',
scope: 'your scopes divided with space'
},
tokenEndpoint:
environment.identityServerUrl + AUTH_OPTIONS_DEFAULTS.tokenEndpoint
})
Options:
export interface AuthOptions<T> {
userType?: new() => T;
tokenName?: string;
tokenEndpoint?: string;
stsParams?: OAuthParams;
}
export interface OAuthParams {
scope: string;
client_id: string;
client_secret: string;
}
It is possible to use custom user that extends class User:
export class CustomUser extends User {
public custom_claim: string;
}
To access the claim display mode, you need to pass the enableDevHotkey parameter:
AuthModule.forRoot({
...,
{ enableDevHotkey: true }
})
To enable the mode, press the key combination Ctrl+F7.
Usage
AuthService
AuthService is the main part of authentication and authorization control.
@Inject(AUTH_SERVICE) private authService: AuthService<User>
login(login: string, password: string): Observable<T>
logout(): T
authorize(claim: string | string[] = null)
getUser(): T
user$: BehaviorSubject<T>;
Authorize directive
Checks user claims and removes inner html if user hasn't got specified claim:
<li routerLinkActive="active" *authorize="'app.debtors'">
content
</li>
You might want to hide content for anonymous users:
<li routerLinkActive="active" *authorize>
content
</li>
AuthorizeControl directive
Checks user claims and set 'disabled' attribute for button/input/form, etc.
<button type="button" authorizeControl="users:roles_EDIT">
Button
</button>
Checks user claims and set 'disabled' attribute and styles (pointer-events, opacity) for span/i
<span authorizeControl="users:list_EDIT">
X
</span>
You must handle http statuses by your own. It's project specific. Implement HttpInterceptor and provide it.
reason: https://limezaim.atlassian.net/browse/KRNL-22
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(
private injector: Injector
) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authService = this.injector.get(AUTH_SERVICE);
const router = this.injector.get(Router);
return next.handle(req)
.catch(error => {
if (error && error.status === 401) {
authService.logout();
router.navigateByUrl('/');
}
return throwError(error);
});
}
}
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
Custom AuthService implementation example
class CustomAuthService<T extends User> extends AuthService<T> {
private logoutStatus = false;
constructor (
authApi: AuthApiService,
authTokenService: AuthTokenService,
jwtHelperService: JwtHelperService,
@Inject(AUTH_OPTIONS) options: AuthOptions<T>
) {
super(authApi, authTokenService, jwtHelperService, options);
}
get getLogoutStatus(): boolean {
return this.logoutStatus;
}
logout() {
const logoutResult = super.logout();
this.logoutStatus = true;
return logoutResult;
}
}
AuthModule.forRoot({ userType: User }, CustomAuthService)
Cookie storage
npm install ngx-cookie@^4.1.2
Commands
Tests
npm run test
npm run test:watch
Build
npm run build
Release
npm run release