미해결
Slack 클론 코딩[백엔드 with NestJS + TypeORM]
AuthGuard에 관한 질문
제로초님 안녕하세요.
AuthGuard를 이용해 로그인 처리를 하고있습니다. 세션 쿠키 방식을 사용하고 있구요.
로그인 방식이
1. 리퀘스트에 쿠키가 있으면 => 쿠키로 세션을 불러와서 안에 들어가있는 user id를 가져와서 디비에서 검색후 로그인
2. 리퀘스트에 쿠키가 없으면 => 디비에서 id와 password를 검색하고 있을 시 세션에 저장하고 로그인. 없으면 UnauthorizedException
이렇게 되는 걸로 파악했는데요.
리퀘스트에 쿠키가 있고 세션에도 저장된 게 있지만 디비에서 유저가 지워졌을 경우, 1번 방식에서 user id가 없기 때문에, 그냥 500 에러가 발생하고 끝나는데요.
저는 이 때, 다시 2번 방식으로 돌리는 플로우로 가고 싶습니다.(쿠키 세션으로 불러지는 정보가 없을 경우, 디비에서 id와 password를 가지고 검색 후 처리)그래서 막연히 LocalAuthGuard 에 null 값을 주고 실행해 봤는데, 아무 동작도 하지 않았습니다.
어떻게하면 좋을지 조언을 듣고 싶습니다.
```ts
local-auth.guard.ts@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {
async canActivate(context: ExecutionContext): Promise<boolean> {
if (context) {
const can = await super.canActivate(context);
if (can) {
const request = context.switchToHttp().getRequest();
console.log('쿠키 사용해서 로그인 : ', request);
await super.logIn(request);
}
}
return true;
}
}
``````tslocal.strategy.ts
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super({ usernameField: 'email', passwordField: 'password' });
}
async validate(email: string, password: string, done: CallableFunction) {
const user = await this.authService.validateUser(email, password);
if (!user) {
throw new UnauthorizedException();
}
return done(null, user);
}
}
```
```ts
local.serializer.ts
@Injectable()
export class LocalSerializer extends PassportSerializer {
constructor(
private readonly authService: AuthService,
private readonly localStrategy: LocalStrategy,
private readonly localAuthGuard: LocalAuthGuard,
private readonly reLocalAuthGuard: ReLocalAuthGuard,
@InjectRepository(HpMasterUserRepository, 'homepage-db')
private userRepository: UserRepository,
) {
super();
}
serializeUser(User: User, done: CallableFunction) {
done(null, user.UserId);
}
async deserializeUser(userId: number, done: CallableFunction) {
try {
const user =
await this.userRepository.selectHpMasterUserById(
userId,
);
if (hpMasterUser) {
done(null, hpMasterUser.userId); // req.user
}
await this.localAuthGuard.canActivate(null);
// this.reLocalAuthGuard.canActivate(null);
} catch (err) {
// throw new UnauthorizedException();
done(err);
}
}
}
```
```ts
auth.service.ts
@Injectable()
export class AuthService {
constructor(private userService: UserService) {}
async validateUser(email: string, password: string) {
const user = await this.userService.masterUserLogin(email, password);
if (!user) {
return null;
} else if (user) {
const { password, ...userWithOutPassword } = user;
return userWithOutPassword;
}
return null;
}
}
```