FrontEnd

angular 구글로 로그인 구현

고태광이 2019. 8. 18. 16:18

안녕하세요 오늘은 angular 로 OAuth2(구글로 로그인) 부분 만드는 법을 알아보도록 하겠습니다.

저는 구글로 로그인이 되게끔 할꺼에요 (카카오, 페이스북도 있지만..) 

 

처음에는 파이어베이스 콘솔에 들어가서 새 프로젝트를 생성하면 됩니다.

https://firebase.google.com/

 

그리고 프로젝트를 추가 합니다.

 

 프로젝트 생성 후 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와 통신하는 법을 알아보겠습니다.