1 MEAN Stack Front to Back MEANAuth App
1 MEAN Stack Front to Back (MEANAuth. App) 6. Register Component, Validation & Flash messages 7. Auth Service & User Registration
목차 2 1. 환경 구축 2. Express Setup & Routes 3. User Model and Register 4. API authentication and Token 5. Angular 4 Components & Routes 6. Register Component, Validation & Flash messages 7. Auth Service & User Registration 8. Login & Logout 9. Protected Requests & Auth Guard 10. App Deployment to Heroku
3 6. Register components 1. Register components 2. Validation 3. Flash messages
Home component 4 home/home. component. html <div class="jumbotron text-center"> <h 1>MEAN Authentication App</h 1> <p class="lead">Welcome to our custom MEAN authentication app</p> <div> <a class="btn btn-primary" [router. Link]="['/register']">Register</a> <a class="btn btn-default" [router. Link]="['/login']">Login</a> </div> <div class="row"> <div class="col-md-4"> <h 3>Express Backend</h 3> <p>A rock solid Node. js/Express server using Mongoose to organize models and query the database. </p> </div> <div class="col-md-4"> <h 3>Angular/CLI</h 3> <p>Angular/CLI to generate components, services and more. Local dev server and easy compilation</p> </div> <div class="col-md-4"> <h 3>JWT Tokens</h 3> <p>Full featured authentication using JSON web tokens. Login and store user data</p> </div> Register 버튼 Login 버튼 메인 페이지 컨텐츠 작성
Home component 5
Register component 6 Register/register. component. ts import { Component, On. Init } from '@angular/core'; @Component({ selector: 'app-register', template. Url: '. /register. component. html', style. Urls: ['. /register. component. css'] }) export class Register. Component implements On. Init { name: string; username: string; email: string; password: string; constructor() { } ng. On. Init() { } on. Register. Submit(){ const user = { name: this. name, email: this. email, username: this. username, password: this. password } } } 사용자 등록 페이지에서는 4개의 사용자 입력정보 사용
Register component 7 Register/register. component. html 사용자 등록 페이지 UI <h 2 class="page-header">Register</h 2> Submit 버튼이 눌리면 <form (submit)="on. Register. Submit()"> on. Register. Submit() 함수가 실행됨 <div class="form-group"> <label> Name </label> <input type="text" [(ng. Model)]="name" name="name" class="form-control"> </div> 사용자 입력값을 ng. Model로 연결 <div class="form-group"> 2 -way binding 제공 <label> Username </label> <input type="text" [(ng. Model)]="username" name="username" class="form-control"> </div> <div class="form-group"> <label> Email </label> <input type="text" [(ng. Model)]="email" name="email" class="form-control"> </div> <div class="form-group"> <label> Password </label> <input type="password" [(ng. Model)]="password" name="password" class="form-control"> </div> <input type="submit" class="btn btn-primary" value="Submit"> </form>
Register component 8 App. module. ts 에 Forms. Module 추가 필요 import { Browser. Module } from '@angular/platform-browser'; import { Ng. Module } from '@angular/core'; import { Forms. Module, Reactive. Forms. Module } from '@angular/forms'; import { Router. Module, Routes } from '@angular/router'; 사용자의 폼 입력을 다루는 모듈을 import하여 중략 app. module. ts에 등록시킴 @Ng. Module({ 중략 imports: [ Browser. Module, Forms. Module, Router. Module. for. Root(app. Routes) ], providers: [], bootstrap: [App. Component] }) export class App. Module { }
Register component 9
사용자 입력값 검증 추가 12 App. module. ts에 서비스 등록 � 다음 내용 추가 중략 import { Validate. Service } from '. /services/validate. service'; 중략 providers: [Validate. Service],
사용자 입력값 검증 추가 13 validate. service. ts 파일 수정 import { Injectable } from '@angular/core'; 검증 관련 서비스 함수 2개를 등록 @Injectable() export class Validate. Service { constructor() { } validate. Register(user) { if(user. name == undefined || user. email == undefined || username == undefined || user. password == undefined) { return false; 4개의 사용자 입력값 모두를 입력해야 } else { return true; } } 이메일주소의 유효성을 검증하는 코드 validate. Email(email){ var re = /^(([^<>()[]\. , ; : s@"]+(. [^<>()[]\. , ; : s@"]+)*)|(". +"))@ (([[0 -9]{1, 3}. [0 -9]{1, 3}])|(([a-z. A-Z-0 -9]+. )+[a-z. A-Z]{2, }))$/; return re. test(email); } } 구글 검색: javascript validate email 함
register. component. ts 파일 수정 14 import { Component, On. Init } from '@angular/core'; import { Validate. Service } from '. . /services/validate. service'; @Component({ selector: 'app-register', template. Url: '. /register. component. html', style. Urls: ['. /register. component. css'] }) export class Register. Component implements On. Init { name: string; username: string; email: string; password: string; constructor(private validate. Service: Validate. Service) { } ng. On. Init() { } 서비스 함수를 이용 컴포넌트에서 서비스를 등록 on. Register. Submit(){ const user = { name: this. name, email: this. email, username: this. username, password: this. password } // Required Fields if(!this. validate. Service. validate. Register(user)){ console. log('Please fill in all fields'); return false; } // Validate Email if(!this. validate. Service. validate. Email(user. email)){ console. log('Please use a valid email'); return false; } } }
Flash Message 기능 추가 17 App. module. ts 에 적용 import { Validate. Service } from '. /services/validate. service'; import { Flash. Messages. Module } from 'angular 2 -flash-messages'; 중략 imports: [ Browser. Module, Forms. Module, Router. Module. for. Root(app. Routes), Flash. Messages. Module ], 중략
Flash Message 기능 추가 18 App. component. html 파일 수정 <app-navbar></app-navbar> <div class="container"> <flash-messages></flash-messages> <router-outlet></router-outlet> </div> Flash message는 메뉴바 아래, 메인 콘텐츠 위에 표시함
Flash Message 기능 추가 19 Register. component. ts 파일 수정 import { Component, On. Init } from '@angular/core'; import { Validate. Service } from '. . /services/validate. service'; import { Flash. Messages. Service } from 'angular 2 -flash-messages'; 중략 constructor(private validate. Service: Validate. Service, private flash. Message: Flash. Messages. Service) { } 중략 // Required Fields if(!this. validate. Service. validate. Register(user)){ this. flash. Message. show('Please fill in all fields', {css. Class: 'alert-danger', timeout: 3000}); return false; } // Validate Email if(!this. validate. Service. validate. Email(user. email)){ this. flash. Message. show('Please use a valid email', {css. Class: 'alert-danger', timeout: 3000}); return false; } } }
Flash Message 기능 추가 20
21 7. Auth Service & User Registration 1. Auth Service 2. User Registration
사용자 등록시 DB에 저장 23 Auth. service. ts 파일 수정 import { Injectable } from '@angular/core'; Http 서비스를 이용할 준비 import { Http, Headers } from '@angular/http'; Headers 모듈 사용 준비 import 'rxjs/add/operator/map'; Rxjs 사용 준비 @Injectable() export class Auth. Service { 인증토큰, 사용자정보 변수 선언 auth. Token: any; user: any; Http 서비스를 등록 constructor(private http: Http) { } register. User(user){ let headers = new Headers(); headers. append('Content-Type', 'application/json'); return this. http. post('http: //localhost: 3000/users/register', user, {headers: headers}) . map(res => res. json()); Http 서비스로 사용자 정보를 전송 } Observable을 리턴 }
Angular. JS에서의 Http 서비스 24 Angular. JS에서 사용하는 AJAX API
Reactive Programming 25 Reactive Programming이란? � � Reactive programming is programming with asynchronous data streams. An amazing toolbox of functions to combine, create and filter any of those streams.
Reactive. X 26 Reactive. X http: //reactivex. io/ � � Reactive. X is a library for composing asynchronous and eventbased programs by using observable sequences. Reactive. X provides a collection of operators with which you can filter, select, transform, combine, and compose Observables. https: //github. com/Reactive. X/rxjs http: //reactivex. io/rxjs/
Observables, observer, subscribe 27 An Observer Subscribes to an Observable � The observer reacts to whatever item or sequence of items the Observable emits
사용자 등록시 DB에 저장 28 참고: routes/users. js (Backend server의 응답) // Register router. post('/register', (req, res, next) => { let new. User = new User({ 사용자 입력값으로 name: req. body. name, new. User 객체 생성 email: req. body. email, username: req. body. username, password: req. body. password }); User. add. User(new. User, (err, user)=>{ mongo. DB에 저장 if(err) { res. json({success: false, msg: 'Failed to register user'}); } else { res. json({success: true, msg: 'User registered'}); } });
사용자 등록시 DB에 저장 29 App. module. ts 파일에서 auth service 등록 import { Browser. Module } from '@angular/platform-browser'; import { Ng. Module } from '@angular/core'; import { Forms. Module } from '@angular/forms'; import { Http. Module } from '@angular/http'; 필요한 모듈 import 중략 import { Validate. Service } from '. /services/validate. service'; import { Auth. Service } from '. /services/auth. service'; import { Flash. Messages. Module } from 'angular 2 -flash-messages'; 중략 imports: [ Browser. Module, Forms. Module, Http. Module, Router. Module. for. Root(app. Routes), Flash. Messages. Module ], providers: [Validate. Service, Auth. Service], 필요한 서비스 import 모듈 등록 서비스 등록
사용자 등록시 DB에 저장 30 import { Component, On. Init } from '@angular/core'; import { Validate. Service } from '. . /services/validate. service'; import { Auth. Service } from '. . /services/auth. service'; import { Flash. Messages. Service } from 'angular 2 -flash-messages'; import { Router } from '@angular/router'; 중략 constructor( private validate. Service: Validate. Service, private flash. Message: Flash. Messages. Service, private auth. Service: Auth. Service, private router: Router ) { } register. component. ts 파일 수정 필요한 서비스 import Router서비스는 페이지 리다이렉트에 사용 서비스 등록 // Validate Email if(!this. validate. Service. validate. Email(user. email)){ this. flash. Message. show('Please use a valid email', {css. Class: 'alert-danger', timeout: 3000}); return false; } 서버의 응답을 받아서 처리 // Register User Subscribe 메서드 이용 this. auth. Service. register. User(user). subscribe(data => { if(data. success) { this. flash. Message. show('You are now registered and can log in', {css. Class: 'alert-success', timeout: 3000}); this. router. navigate(['/login']); 등록 성공시 로그인 페이지로 리다이렉트 } else { this. flash. Message. show('Something went wrong', {css. Class: 'alert-danger', timeout: 3000}); this. router. navigate(['/register']); 등록 실패시 등록 페이지로 리다이렉트 } });
- Slides: 31