본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


앵귤러, 리엑트, 뷰/Angular Tutorial(old)

앵귤러 튜토리얼 (Angular tutorial) -24 with 파이어 베이스

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2019. 8. 1.

* 제가 다시 작성한 최신 튜토리얼 수정본 입니다. 아래 주소를 통해서 진행하시는 것을 권장 드립니다. ^^

lts0606.tistory.com/328

 

앵귤러 튜토리얼(Angular tutorial) - 1

안녕하세요. 앵귤러에 대해서 알아보기위해 이곳을 찾아주신 분 들께 감사의 말씀 드립니다.^^ 천천히, 초심자도 조금 더 쉽게 접근할 수 있도록 내용을 구성하여 보겠습니다. 어��

lts0606.tistory.com

 

이번시간에는 앵귤러 guard를 통한 로그인 기능에 대해서 살펴 보겠다.

guard는 앵귤러에서 제공하는 기능으로 특정 url로의 요청을 가로챈 뒤에 먼저 할 행동을 정의해주는 역할을 한다.

아래 명령어를 입력해서 한번 만들어보도록 하자.

ng g guard interceptor

첫번째 사진은 "뭘만들래?" 라는 사진이다 첫번째 항목에서 스페이스키를 누른다.
스페이스키를 누른뒤에 엔터를 누르자

 

뭔가 알수없는 코드가 만들어졌다.

소스코드를 살펴보자.

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class InterceptorGuard implements CanActivate {
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return true;
  }
  
}

엄청난 코드다...너무 어려울정도로...

일단 천천히 살펴보면 next라는 변수에 ActivatedRouteSnapshot의 형태의 객체가 존재하고, state라는 변수에RouterStateSnapshot 객체가 존재한다. 두 파라미터는 앵귤러가 넣어 주는 내용이며 일단 지금은 몰라도 된다.

내용이 어려우니 아래처럼 사용해도 사실 무방하다.

내용을 이해하지 말고 리턴값에 주목하자.

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class InterceptorGuard implements CanActivate {
  canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot){
    return true;
  }
  
}

위 처럼 수정하면 조금 더 보기 편해졌다.

아직 잘 모르겠지만 간단하게 설명하면 해당 return값이 true이면 접근가능, false이면 접근 불가능의 의미이다.

 

다음으로 app.module.ts파일을 수정해보도록 하자.

//생략..

import { RouterModule,Routes} from '@angular/router'; //라우터
import { InterceptorGuard } from './interceptor.guard';  //인터셉터
const router : Routes = [  //라우팅
  {path : '' , component : LoginComponent},  
  {path : 'board' , component : AppComponent, canActivate:[InterceptorGuard]}, //요 부분!!
  {path: '**',redirectTo: ''}  
]


const fireEnvironment = {
  production: true,
  firebase: {
    //생략..
  }
};

//생략..

자세히보면 router변수에 board라는 부분에 아까 만들어준 인터셉터 형태의 객체를 등록하였다. canActivate 부분에 인터셉터형식(interceptor.guard.ts)의 객체를 등록해주면 사실상 세팅은 끝이났다.

InterceptorGuard 부분에서 리턴값이 true이면 해당 페이지로 이동이되고, false이면 이동이 불가능 하다.

테스트를 해보자. 리턴 형식을 false로 하였을 때 board 페이지로 이동하는지 확인해보자.

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class InterceptorGuard implements CanActivate {
  canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot){
    return false; //요부분을 false로 바꾼다.
  }
  
}

코드를 수정한 뒤에 접근하여 보자.

아무것도 안나온다..

분명 localhost:4200/board로 접속하였는데 사진과같은 모습을 만나게 되었다.

즉, 요 부분에 어떠한 조건절을 통해 로그인 여부를 컨트롤 할 수 있는 것이다. 다시 true로 바꾸면 기존에 보았던 화면을 만날 수 있다.

 

그럼 이제, 간단한 로그인을 만들어보자. 

기존에 만들어둔 login.component 파일들을 아래처럼 바꾸어 보자.

파일 : login.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  private id ;
  private password;

  constructor() { }

  ngOnInit() {
  }
  
  login(){
    if(this.id == 'admin' && this.password == '1234'){
      console.log(this.id, this.password);
    }
  }
}

파일 : login.component.html

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<div class="container">
    <br><br>
    <input type='text' class='form-control' [(ngModel)]="id"/>
    <br/>
    <input type='text'class='form-control' [(ngModel)]="password"/>
    <br/>
    <button class='btn btn-success' (click)='login()'>LogIn</button>
</div>

 

로그인 정보를 유지할 서비스를 한개 더 만들어보자. 해당 서비스는 session이라는 이름을 부여하였다.

해당 서비스에는 로그인 성공시 로그인한 아이디값을 가지고 있도록 만들어 보도록 하겠다.

ng g service session

세션 이름은 서비스로 하였다.

해당 서비스를 아래처럼 수정하자.

정보를 저장하고 가져올 메소드 2개를 만들었다. 내용이 직관적이라 어렵지 않다.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class SessionService {
  
  constructor() { 

  }

  setInfo(userId){
    localStorage.setItem('id', userId);
  }

  getInfo() : string{
    return localStorage.getItem('id');
  }
}

localStorage라는 곳에 정보를 저장하는 서비스가 만들어졌다. localStorage는 앵귤러에서 제공하는 간단한 문자형태를 저장하는 기능이며 일종의 쿠키형식으로 관리가 된다. 

즉, 로그인 성공시 setInfo가 호출되어 정보를 저장하고 인터셉터가 getInfo를 호출해서 로그인 여부를 판단하게 될 것이다.

나중에 로그아웃, 타임아웃 기능을 추가할 때 localStorage에 대해서 조금 더 살펴보도록 하자.

 

메인 모듈(app.module.ts)에 해당 서비스를 등록하자.

//..생략
@NgModule({
  //..생략
  providers: [ 
    //..생략
    SessionService  //해당 서비스를 제공하도록 등록하자.
  ], 
})
export class AppModule { }

 

이제 로그인정보가 유지되는 서비스가 등록되었다.

다음단계는 로그인 성공시 해당 서비스에 로그인 정보 넣기와, 인터셉터 역할을 하는 guard에 해당 정보를 조회해서 조회값이 있으면 true 없으면 false로 접근여부를 판단하는 작업만 남았다.

login.component.ts의 내용을 바꾸어보자.

import { Component, OnInit } from '@angular/core';
import {SessionService} from '../session.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  private id ;
  private password;

  constructor(private session : SessionService) {  //로그인 정보를 공유할 서비스

  }

  ngOnInit() {
  }
  
  login(){
    if(this.id == 'admin' && this.password == '1234'){
      console.log(this.id, this.password);
      this.session.setInfo(this.id);  //서비스에 기록한다.
    }
  }
}

마지막으로 인터셉터를 수정하자.

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import {SessionService} from './session.service';

@Injectable({
  providedIn: 'root'
})
export class InterceptorGuard implements CanActivate {

  constructor(private session : SessionService) {  //로그인 정보를 공유할 서비스

  }

  canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot){
    var info : any = this.session.getInfo();
    if(info != null){
      return true;
    }
    return false; //요부분
  }
  
}

 

자, 이제 로그인화면에서 admin과 1234를 입력하여보자.

로그인 정보를 공유하는 서비스에 등록이 되었다!!

다음으로 board주소를 입력하여보자.

드디어 만난 board..

이상없이 잘 나옴을 확인 할 수 있다.

 

정신없이 지나간 내용인 것 같다.

정리하여보면,

1. 인터셉터 역할을 하는 guard를 만들자(interceptor.guard.ts).

2. guard는 router영역에서 canActivate에 등록해서 해당 페이지에 접근하기전 동작하게 한다.

2. service를(session.service.ts) 한개 더 만들어 로그인 여부를 localStorage에 저장하게 한다.

3. guard에서는 해당 서비스를 주입받아 로그인 정보에 따라 true, false여부를 리턴하게 한다.

 

 

이번시간에는 앵귤러 guard를 통한 로그인 기능에 대해서 살펴보았다.

로그인하는 부분을 파이어베이스 연동으로 바꾸는 것은 생략하도록 한다.

다음시간에는, 로그인 이후에 페이지 리 다이렉트와 로그아웃기능, 로그인시간 만료에 대해서 살펴보도록 하자.

src.zip
0.01MB

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글