I have successfully implemented jwt auth in my lb4 app using custom service which implements userservice from @loopback/authentication-jwt
. Everything is working fine for authentication.
But when I go for authorization AuthorizationMetadata
contains only two fields - id and name. While issuing token I have used many fields one of which was role
.
But now all other fields like role or email are undefined. Thus whenever I try to access controller protected with authorize decorator I get 501 access denied.
I can't get why other properties are undefined.
Thank you in advance
custom-service
export class CustomUserService implements UserService<User, Credentials> {
// other code
convertToUserProfile(user: User): UserProfile {
let address = ''
if (user.address) {
address = user.address
}
const profile = {
[securityId]: user.id!.toString(),
name: user.name,
id: user.id,
email: user.email,
role: user.role,
address: user.address
}
console.log(profile)
return profile
}
}
login controller
import {authenticate, TokenService, UserService} from '@loopback/authentication';
export class UserController {
constructor(@inject(SecurityBindings.USER, {optional: true})
public users: UserProfile,){}
//@get login
async login(
@requestBody(CredentialsRequestBody) credentials: Credentials,
): Promise<{token: string}> {
// ensure the user exists, and the password is correct
const user = await this.userService.verifyCredentials(credentials);
// convert a User object into a UserProfile object (reduced set of properties)
const userProfile = this.userService.convertToUserProfile(user);
// create a JSON Web Token based on the user profile
const token = await this.jwtService.generateToken(userProfile);
return {token};
}
authorizer.ts
import {AuthorizationContext, AuthorizationDecision, AuthorizationMetadata} from '@loopback/authorization';
export async function basicAuthorization(
authorizationCtx: AuthorizationContext,
metadata: AuthorizationMetadata,
): Promise<AuthorizationDecision> {
// No access if authorization details are missing
let currentUser: UserProfile;
if (authorizationCtx.principals.length > 0) {
const user = _.pick(authorizationCtx.principals[0]
, [
'id',
'name',
'role',
'email',
'address'
]);
console.log(user) // contains only id and name
// other code
}
}