I am using Angular+Nest to develop a website. I have created a service(Angular) so that client can get user\'s information from server when project start up(the same as fresh).
Write a conditional logic in the AuthGuard to check if a user is provided in the request.
If you really insist on this way (see comments), you can use Interceptors:
@Injectable()
export class GetUserInterceptor implements NestInterceptor {
constructor(private readonly authService: AuthService) {
}
async intercept(context: ExecutionContext, next: CallHandler) {
const request = context.switchToHttp().getRequest()
const item = await this.authService.getByToken(/* extract me from headers*/)
request.user = item
return next.handle()
}
}
so AuthGuard is not needed.
If you got totally different approach in mind, let me know - will try to help.
Will try to serve a bit more detailed example, which includes passport
under the hood. It assumes that passport
is used and that Authorization
token is being sent.
const RegisteredPassportModule = PassportModule.register({ defaultStrategy: 'bearer' })
HttpStrategy
to some AuthModule
PassportModule.register({ defaultStrategy: 'bearer' })
to imports to AuthModule
Then:
AuthService
is a service (and a part of AuthModule
) that allows to find given user via token sent via token passed via Authorization
header, directly from the database.
import { Strategy } from 'passport-http-bearer';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';
@Injectable()
export class HttpStrategy extends PassportStrategy(Strategy) {
constructor(private readonly authService: AuthService) {
super()
}
async validate(token: string) {
const user = await this.authService.findUserByToken(token);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
Usage is after all quite simple (you can put the guard for either method of controller):
@UseGuards(AuthGuard())
@Get()
someMethod(@Req() request: RequestWithUser, ...) {
// ...
}
Where RequestWithUser
is just:
import { User as UserEntity } from '../../models/user.entity'
export type RequestWithUser = Request & { user: UserEntity }
and the /user
endpoint would be just returning request.user
I hope this helps!