[NestJS] - 20. 인증과 인가 - OAuth2 Google 소셜 로그인
많은 웹 서비스들을 보면 페이스북, 카카오, 네이버, 구글 등으로 소셜 로그인을 지원하는 것을 볼 수 있다.
이렇게 다른 믿을만한 플랫폼에 인증을 대신 맡기는 것을 OAuth 인증이라고 하는데
이번 포스팅에서는 구글 OAuth 인증에 대해서 알아보도록 하자.
https://sjh9708.tistory.com/46
패키지 설치
yarn add passport-google-oauth20 |
Google OAuth의 Passport Strategy를 사용하기 위해 다음의 패키지를 설치하자.
구글 계정 세팅
구글의 OAuth를 이용하기 위해서는 Application 프로젝트를 생성하고 App에서 이용할 수 있도록 세팅을 해주어야 한다..
GCP 프로젝트 생성
GCP Console에서 OAuth를 이용하기 위해서 프로젝트를 생성한다.
사용자 인증 정보 설정하기
OAuth를 이용할 때 사용할 클라이언트 ID와 Secret을 발급받기 휘애서 사용자 인증 정보 만들기 -> OAuth 클라이언트 ID 를 만든다.
위에서 만든 후 발급받은 ID와 Secret을 App에서 사용할 것이다.
클라이언트 ID를 만들 때 승인돤 리디렉션 URI 항목에 소셜 로그인 성공 후 로그인을 처리할 API 주소를 입력해야 한다.
Google People API 사용 설정
로그인 시 사용자의 정보를 받아오기 위해서 People API(people.googleapis.com)를 사용 추가해준다.
Google Passport Strategy 만들기
▶ jwt-oauth-google.strategy.ts
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-google-oauth20';
//Google Strategy 사용
export class JwtGoogleStrategy extends PassportStrategy(Strategy, 'google') {
constructor() {
super({
clientID: process.env.GOOGLE_AUTH_CLIENT, //ID
clientSecret: process.env.GOOGLE_AUTH_SECRET, //PWD
callbackURL: 'http://localhost:3000/auth/login/google', //성공 시 URL
scope: ['email', 'profile'], //성공시 받을 데이터
});
}
validate(accessToken, refreshToken, profile) {
console.log(profile);
return {
email: profile.emails[0].value,
name: profile.displayName,
};
}
}
구글 인증을 위한 Strategy를 하나 생성해주었다.
- 이번엔 Strategy를 google-oauth20에서 import해주었다. 즉, Strategy의 종류가 이전에 사용하던 종류와는 다르다.
- 생성자 : GCP에서 발급받은 ID와 Secret을 입력하고, callbackURL에 구글 로그인 성공 시 처리할 URL을 입력해준다. 해당 URL은 아까 승인된 URI 리다이렉션 목록에 있어야 한다. scope에는 로그인 성공 시 구글 측으로부터 받을 데이터를 입력해준다.
- validate에서는 accessToken, refreshToken, profile을 성공 시 구글측으로부터 받으며, 해당 Strategy Guard를 사용할 때 인가 성공 시 넘겨줄 데이터들을 작성한다.
Google 로그인 API 만들기
▶ auth.controller.ts
@UseGuards(AuthGuard('google'))
@Get('login/google')
async loginGoogle(@Req() req: Request & IOAuthUser, @Res() res: Response) {
//1. 가입확인
let user = await this.userService.findOne(req.user.email);
//2. 회원가입
if (!user) {
const input = {
email: req.user.email,
password: 'OAuth',
name: req.user.name,
age: 0,
} as CreateUserInput;
user = await this.userService.create(input);
}
//3. 로그인
this.authService.setRefreshToken({ user, res });
res.redirect(
'http://localhost:5500/09_Authorization/09-04-oauth/frontend/success.html',
);
}
- 앞에서 만든 Google Strategy Guard를 사용하였다. 이제 해당 API에 접근하기 전에 구글 로그인이 성공해 있어야 한다.
- 구글의 인가를 통과하면 해당 API가 실행되게 된다.
- 해당 코드에서는 내부 회원가입이 되어있지 않으면 구글에서 제공받은 이메일과 이름으로 회원가입을 진행하고 있다. 용도에 맞게 회원가입이 되어있지 않으면 회원가입 폼으로 이동시키는 등 작성하기 나름이다.
- 회원가입 완료 후 로그인 처리를 위해서 Refresh Token을 발급하였다. 이제 클라이언트는 Refresh Token으로 Access Token을 발급받을 수 있다.
- 클라이언트에서 /auth/login/google 요청을 하게 되면 OAuth에 의해서 구글 로그인 창으로 Redirect되게 된다. API 완료 시 클라이언트가 어떤 페이지로 전환할지를 res.redirect()로 설정해준다.
이제 구현된 OAuth 인증과 인가 과정을 정리해보면
1. 클라이언트의 구글 로그인 요청
2. 클라이언트는 구글 로그인 페이지로 이동한다.
3. 로그인 성공 시 구글은 인가를 위한 Google Access Token을 발급한다.
4. 발급받은 토큰을 이용하여 AuthGuard('google')을 뚫었다면, 서비스의 회원가입이 되어있지 않았다면 가입시킨다.
5. Refresh Token을 발급한다.
6. 클라이언트는 로그인 성공 화면으로 이동시킨다.
▶ social-login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>소셜로그인</title>
</head>
<body>
<a href="http://localhost:3000/auth/login/google">구글로그인</a>
</body>
</html>
클라이언트 측에서 구글 로그인 요청을 하려면 단지 이런 식으로 요청하면 된다.
'Backend > Node.js (NestJS)' 카테고리의 다른 글
[NestJS] - 22. NestJS Logging - Winston 연결하기 (0) | 2023.03.05 |
---|---|
[NestJS] - 21. 결제 프로세스와 Transaction Isolation (0) | 2023.03.05 |
[NestJS] - 19. JWT 토큰 인가 - PassportStrategy/Guard 사용과 토큰 재발급 (0) | 2023.03.04 |
[NestJS] - 18. JWT 토큰 인증 - 회원가입/로그인 구현 (1) | 2023.03.04 |
[NestJS] - 17. TypeORM에 여러개의 데이터베이스 연결하여 사용하기 (0) | 2023.02.25 |