javascript - Kako pristupiti bazi podataka iz NestJS guarda
Trenutno pokušavam učiti nestjs, za to sam slijedio službeni (mačji) vodič kako bih izgradio osnovni sustav za autentifikaciju korisnika.
Kada pristupite API-ju da promijenite korisničko ime ili lozinku, zahtjev bi trebao provjeriti je li korisnik valjan (čitanje korisnika iz baze podataka). Za spremanje korisnika već imam MongoDB vezu.
Trenutno se mučim kako mogu dobiti pristup/datoteku baze podataka u stražaru.
Stražar radi, ali vraća samo true, pokušao sam ubaciti svoj modul baze podataka, ali bez uspjeha.
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return this.validateRequest(request);
}
validateRequest(execContext: ExecutionContext): boolean | Promise<boolean> | Observable<boolean>{
const request = execContext.switchToHttp().getRequest();
const user = request.user;
return true;
}
}
Je li to pravi pristup proširiti klasu UserService metodom findOne i ubrizgati je u servis?
@Injectable()
export class UserService{
constructor(@Inject('USER_MODEL') private readonly userModel: Model<User>){}
async create(createUserDto: CreateUserDto): Promise<User>{
const createdUser = new this.userModel(createUserDto);
return await createdUser.save();
}
async update(updateUserDto: UpdateUserDto): Promise<User>{
const updateUser = new this.userModel(updateUserDto);
return await this.userModel.updateOne({loginname: updateUser.loginname}, this.getUpdateQueryFromUserModel(updateUser));
}
async delete(deleteUserDto: DeleteUserDto): Promise<User>{
const deleteUser = new this.userModel(deleteUserDto);
return await this.userModel.deleteAll({loginname:deleteUser.loginname}).exec();
}
async findAll(): Promise<User[]> {
return await this.userModel.find().exec();
}
getUpdateQueryFromUserModel(userModel: Model<User>): Object {
let query = {};
if(userModel.dispname !== undefined && userModel.dispname !== null){
query["dispname"] = userModel.dispname;
}
if(userModel.pw !== undefined && userModel.pw !== null){
query["pw"] = hash.sha256().update(userModel.pw).digest('hex');
}
return query;
}
}
Možete li mi molim vas reći kako izgleda pravi pristup? Hvala unaprijed!
Odgovor #1
Pronašao sam rješenje za pristup bazi podataka, možeš ga direktno umetnuti (prije sam to pokušao, ali nije uspjelo zbog drugog problema).
@Injectable()
export class AuthGuard implements CanActivate {
constructor(@Inject('UserService')private readonly userService:UserService){}
canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return this.validateRequest(request);
}
async validateRequest(execContext: ExecutionContext): Promise<boolean>{
const request = execContext.switchToHttp().getRequest();
const user = request.user;
console.log(await this.userService.findAll());
return new Promise<boolean>((resolve, reject) => {
return true;
});
}
}
Moj kod sada izgleda ovako s umetnutom servisom u konstruktor, ali još uvijek ne radi u potpunosti, jer kada pokušam pokrenuti execContext.switchToHttp().getRequest() liniju, dobijem grešku switchToHttp nije funkcija, može li mi netko pomoći?
Pozdravi Pascal
Odgovor #2
ovo je moja implementacija i funkcionira dobro
import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common'
import { Reflector } from '@nestjs/core'
import { IS_PUBLIC_KEY } from 'src/decorators'
import { IResourcePermission, RESOURCE_PERMISSION_KEY } from 'src/decorators/resource-permission.decorator'
import { RolesPermissionsLogicService } from 'src/modules/roles-permissions/services/roles-permissions-logic.service'
@Injectable()
export class AuthorizeGuard implements CanActivate {
constructor(
private readonly rolesPermissionsLogicService: RolesPermissionsLogicService,
private reflector: Reflector,
) {}
canActivate(context: ExecutionContext): Promise<boolean> {
return this.validateRequest(context)
}
async validateRequest(ctx: ExecutionContext): Promise<boolean> {
const isRoutePublic = this.reflector.get<string>(IS_PUBLIC_KEY, ctx.getHandler())
const resourcePermission = this.reflector.get<IResourcePermission>(RESOURCE_PERMISSION_KEY, ctx.getHandler())
if (isRoutePublic || !resourcePermission) {
return true
}
const { user } = ctx.switchToHttp().getRequest()
const rolePermissions = await this.rolesPermissionsLogicService.getOneRole({
name: user.userRole,
permissions: {
$elemMatch: {
name: resourcePermission.resource,
[`actions.${resourcePermission.scope}`]: true,
},
},
})
if (!rolePermissions) {
throw new UnauthorizedException('Not authorized to access this resource')
}
return true
}
}
