angular 구글로 로그인 구현
안녕하세요 오늘은 angular 로 OAuth2(구글로 로그인) 부분 만드는 법을 알아보도록 하겠습니다.
저는 구글로 로그인이 되게끔 할꺼에요 (카카오, 페이스북도 있지만..)
처음에는 파이어베이스 콘솔에 들어가서 새 프로젝트를 생성하면 됩니다.
그리고 프로젝트를 추가 합니다.
프로젝트 생성 후 web app 아이콘을 클릭합니다. 그리고 config 정보를 가져 옵니다.
그리고 authentication 탭에 들어가 이메일과 구글 계정으로 로그인 할 수 있게끔 설정을 해줍니다.
그 후 angular프로젝트에서 firebase를 설치합니다.
npm install firebase @angular/fire --save
설치가 완료되었으면 app.module.ts 파일을 업데이트 해야합니다.
import {AngularFireModule} from '@angular/fire';
import {AngularFireAuthModule} from '@angular/fire/auth';
const firebaseConfig = {
apiKey: '#######',
authDomain: '###.###.com',
databaseURL: 'https://##.####.com',
projectId: '####',
storageBucket: '',
messagingSenderId: '#####',
appId: '####'
};
@NgModule({
imports: [
......
, AngularFireModule.initializeApp(firebaseConfig)
, AngularFireAuthModule
],
providers: [],
bootstrap: [AppComponent]
})
세팅을 모두 하였으면, login component를 만듭니다.
ng g c page/admin/login
다음으로는 라우터 세팅을 해줍니다.
import {RouterModule, Routes} from '@angular/router';
import {NgModule} from '@angular/core';
import {LoginComponent} from './page/admin/login/login.component';
const appRoutes: Routes = [
{path: 'login', component: LoginComponent}
];
@NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export default class AppRoutingModule {}
그리고 auth service를 만들어 줍니다.
ng g s service/auth
서비스 안에는 유저 데이터를 저장하기위해 user 변수를 선언하고, Firebase authentication 과 router를 주입해줍니다.
import { Injectable } from '@angular/core';
import {User} from 'firebase';
import {AngularFireAuth} from '@angular/fire/auth';
import {Router} from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthService {
user: User;
constructor(public afAuth: AngularFireAuth) { }
}
그리고 constructor 안에 authentication state를 subscribe 하는 코드를 넣습니다. 만약 유저가 로그인 되어있다면 브라우저의 로컬 스토리지에 저장하고, 아니면 null을 저장합니다.
this.afAuth.authState.subscribe(user => {
if (user) {
this.user = user;
localStorage.setItem('user', JSON.stringify(this.user));
} else {
localStorage.setItem('user', null);
}
});
그리고 필요한 함수들을 만들어줍니다. 저는 구글로로그인, 로그아웃, 현재 로그인되어있는지 아닌지 판단하는 3개 함수를 만들었습니다.
async loginWithGoogle() {
return await this.afAuth.auth.signInWithPopup(new auth.GoogleAuthProvider());
}
isUserLoggedIn() {
return JSON.parse(localStorage.getItem('user'));
}
async logout() {
return await this.afAuth.auth.signOut();
}
그리고 아까 만들었던 login component를 세팅해줍니다.
import {Component, OnInit} from '@angular/core';
import {AuthService} from '../../../service/auth.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
userDetails: any;
responseMessageType = '';
responseMessage = '';
constructor(private authService: AuthService) {
}
showMessage(type, msg) {
this.responseMessageType = type;
this.responseMessage = msg;
setTimeout(() => {
this.responseMessage = '';
}, 2000);
}
isUserLogin() {
this.userDetails = this.authService.isUserLoggedIn();
}
logoutUser() {
this.authService.logout()
.then(res => {
console.log(res);
this.userDetails = undefined;
localStorage.removeItem('user');
}, err => {
this.showMessage('danger', err.message);
});
}
googleLogin() {
this.authService.loginWithGoogle()
.then(res => {
console.log(res);
this.isUserLogin();
}, err => {
this.showMessage('danger', err.message);
});
}
ngOnInit() {
}
}
<div class="row">
<div class="text-center" style="width: 100%;margin: 20px;">
<h4>Angular 7 Email/ Password & Google Login Using Firebase Demo</h4>
</div>
<div class="" style="width: 500px; margin: auto">
<div class="card">
<!-- When Uses is Not Logged In -->
<div class="card-body" *ngIf="!userDetails">
<div class="form-group text-center">
<button (click) = googleLogin()>login with google</button>
</div>
</div>
<!-- When Uses is Logged In using Email or Google Account -->
<div class="card-body" *ngIf="userDetails">
<div class="row">
<div class="col-sm-12">
<ul class="list-group">
<li class="list-group-item">Display Name:
{{userDetails['displayName']}}</li>
<li class="list-group-item">Email: {{userDetails['email']}}</li>
<li class="list-group-item">Is Email Varified:
{{userDetails['emailVerified']}}</li>
<li class="list-group-item">
<button type="button" class="btn btn-danger"
(click)="logoutUser()">Logout</button>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="alert alert-{{responseMessageType}}" role="alert"
*ngIf="responseMessage.length">
{{responseMessage}}
</div>
</div>
</div>
해당 프로젝트를 실행하면 아래와 같이 구글로 로그인 버튼이 나옵니다.
클릭을 하게되면 구글 어카운트로 넘어가고, 로그인을 할 수 있습니다.(ux는 아직..안한거에요)
이런 식으로 하면 초기 세팅은 끝났습니다. 다음시간에는 로그인 관련하여 B/E와 통신하는 법을 알아보겠습니다.