-
Notifications
You must be signed in to change notification settings - Fork 9
/
JWT.strategy.ts
54 lines (50 loc) · 1.82 KB
/
JWT.strategy.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import {Request, HttpErrors} from '@loopback/rest';
import {inject} from '@loopback/core';
import {AuthenticationStrategy,
AuthenticationMetadata,
AuthenticationBindings,
TokenService,
} from '@loopback/authentication';
import {MyUserProfile,
UserPermissionsFn,
RequiredPermissions,} from '../types';
import {MyAuthBindings,} from '../keys';
export class JWTStrategy implements AuthenticationStrategy{
name: string = 'jwt';
constructor(
@inject(AuthenticationBindings.METADATA)
public metadata: AuthenticationMetadata,
@inject(MyAuthBindings.USER_PERMISSIONS)
protected checkPermissons: UserPermissionsFn,
@inject(MyAuthBindings.TOKEN_SERVICE)
protected tokenService: TokenService,
) {}
async authenticate(request: Request): Promise<MyUserProfile | undefined> {
const token: string = this.extractCredentials(request);
try{
const user: MyUserProfile = await this.tokenService.verifyToken(token) as MyUserProfile;
return user;
} catch (err) {
Object.assign(err, {code: 'INVALID_ACCESS_TOKEN', statusCode: 401,});
throw err;
}
}
extractCredentials(request: Request): string {
if (!request.headers.authorization) {
throw new HttpErrors.Unauthorized(`Authorization header not found.`);
}
const authHeaderValue = request.headers.authorization;
if (!authHeaderValue.startsWith('Bearer')) {
throw new HttpErrors.Unauthorized(
`Authorization header is not of type 'Bearer'.`,
);
}
const parts = authHeaderValue.split(' ');
if (parts.length !== 2)
throw new HttpErrors.Unauthorized(
`Authorization header value has too many parts. It must follow the pattern: 'Bearer xx.yy.zz' where xx.yy.zz is a valid JWT token.`,
);
const token = parts[1];
return token;
}
}