네이버 로그인 서버 구현해보기
네이버 개발자 사이트 👈클릭!
애플리케이션 등록 탭에서 애플리케이션 이름을 입력하고 사용 API에 네이버 로그인
을 선택한다.
제공되는 정보들을 선택한다.(이름, 이메일주소 등)
서비스 URL
- 도메인 환경이 준비되어있지 않은 경우는 localhost 주소 사용해도 무방하다.콜백 URL
- 로그인 후 네이버로부터 정보를 받아올 콜백 URL 주소를 적어준다.// src/auth/naver.strategy.ts
// naver.strategy.ts
import { Strategy } from 'passport-naver';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { UserService } from 'src/user/user.service';
@Injectable()
export class NaverStrategy extends PassportStrategy(Strategy) {
constructor(private userService: UserService) {
super({
clientID: process.env.NAVER_CLIENT_ID,
clientSecret: process.env.NAVER_CLIENT_SECRET,
callbackURL: process.env.NAVER_CALLBACK_URL,
});
}
async validate(
accessToken: string, // 빼먹지 말고
refreshToken: string, // 일단 하라는 대로 적기..ㅎ
profile: any,
): Promise<any> {
console.log(profile);
const id = profile.id;
const email = profile._json.email;
const name = profile.displayName;
const provider = profile.provider;
const user_profile = {
id,
email,
name,
provider,
};
return user_profile;
}
}
// src/auth/naver-auth.guard.ts
import { AuthGuard } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
@Injectable()
export class NaverAuthGuard extends AuthGuard('naver') {}
NAVER_CLIENT_ID=""
NAVER_CLIENT_SECRET=""
NAVER_CALLBACK_URL="http://localhost:3000/user/naver/login"
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './jwt.strategy';
import { UserModule } from 'src/user/user.module';
import { NaverStrategy } from './naver.strategy';
import { NaverAuthGuard } from './naver-auth.guard';
@Module({
imports: [
PassportModule.register({ defaultStrategy: 'jwt', session: false }),
JwtModule.registerAsync({
useFactory: (config: ConfigService) => ({
secret: config.get<string>('JWT_SECRET_KEY'),
}),
inject: [ConfigService],
}),
UserModule,
],
// 네이버 전략과 가드를 넣어준다.
providers: [JwtStrategy, NaverStrategy, NaverAuthGuard],
exports: [JwtModule, PassportModule],
})
export class AuthModule {}
@UseGuards(AuthGuard('naver'))
@Get('/naver/login')
async loginNaver(@Req() req: Request, @Res() res: Response): Promise<any> {
try {
return await this.userService.OAuthLogin({ req, res });
} catch (error) {
console.error('Error in loginNaver:', error);
res.status(500).json({ error: 'Internal Server Error' });
}
}
async OAuthLogin({ req, res }) {
// 네이버 이메일로 사용자를 찾는다.
let OAuthUser = await this.userRepository.findOne({
where: { email: req.user.email },
});
// 네이버 사용자의 이메일 값을 변수 지정 해주었다.
const email = req.user.email;
// 비밀번호 값은 따로 받아올 수 없기 때문에 user의 아이디 값을 해시화 해서 변수 지정해주었다.
const hashedNaverPassword = await hash(req.user.id, 10);
// 해당 이메일 사용자가 없다면 회원가입 로직처럼 회원 생성 해준다.
// 비밀번호는 user의 아이디 값을 해시화 해서 변수 지정한 값을 사용한다.
if (!OAuthUser) {
OAuthUser = await this.userRepository.save({
email,
name: req.user.name,
password: hashedNaverPassword,
});
}
// 로그인 시 access token을 넣어주기 위해 사용자의 이메일과 요청된 사용자의 ID를 페이로드로 설정한다.
const payload = { email, sub: req.user.id };
res.redirect('/');
return {
message: '로그인 성공',
success: true,
access_token: this.jwtService.sign(payload),
OAuthUser,
};
}
데이터베이스에 아주 잘 들어갔다! 😊