The Web Developer - (Udemy)_ YelpCamp: 인증된 상태에서 추가하기

‍정진철·2022년 8월 22일
0

web devloper (udemy)

목록 보기
26/34

1) Passport 개요

Node앱에 인증을 추가해줌.

  • 사용자를 로그인시킬 때 사용하는 여러 전략 제공.

Passport-Local Mongoose

  • Mongooose 데이터베이스에서 Passport 구현을 쉽게 해줌.


2) 사용자 모델 작성하기


3) Passport 구성하기

app.js

const passport = require('passport');
const LocalStrategy = require('passport-local');
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
  • bcrypt 를 취하지 않아도 register 라는 기능을 통해 솔트/해쉬 암호화 가능.


4) 등록 양식

간단한 회원가입 폼 설정

  • 기본라우트 : /register (GET) (로그인 폼을 제공하는 GET)
    post/register - create a user (로그인을 하기위한 POST)
<users.js> - 라우터 설정
const express = require('express');
const router = express.Router();
const catchAsync = require('../utils/catchAsync');
const User = require('../models/user')

router.get('/register', (req,res) => {
    res.render('users/register')
})

<app.js>
app.use('/', userRoutes )
<register.ejs>

<% layout('layouts/boilerplate')%>
<h1>Register</h1>
<form action="/register" method="POST" class="validated-form" novalidate>
  <div class="mb-3">
    <label class="form-label" for="username">Username</label>
    <input
      class="form-control"
      type="text"
      id="username"
      name="username"
      required
    />
    <div class="valid-feedback">Looks good!</div>
  </div>
  <div class="mb-3">
    <label class="form-label" for="email">Email</label>
    <input class="form-control" type="email" id="email" name="email" required />
    <div class="valid-feedback">Looks good!</div>
  </div>
  <div class="mb-3">
    <label class="form-label" for="password">Password</label>
    <input
      class="form-control"
      type="password"
      id="password"
      name="password"
      required
    />
    <div class="valid-feedback">Looks good!</div>
  </div>
  <button class="btn btn-success">Register</button>
</form>


5) 등록 경로

폼 작성 후 유저로 등록하기. (POST)

폼 등록

동일한 유저네임 있을시.


6) 로그인 경로

{ failureFlash: true, failureRedirect:'/login'}

  • 로그인 실패시 플래시 주면서 다시 /login 경로로 이동시킴.
  • passport.authenticate()
    strategy 설정하고, 인증 절차에 대한 콜백 작성
    인증 에러/실패 및 성공시 처리하는 부분 작성

-> 입력된 비밀번호를 해쉬 처리하는 함수를 작성해 데이터베이스의 해시출력값과 비교해 사용자 인증과정에 사용.

<users.js>

router.get('/login', passport.authenticate('local'), { failureFlash: true, failureRedirect:'/login'}, (req,res)=> {
    req.flash('success', 'WELCOME!!')
    res.redirect('/campgrounds');

})


-------

<login.ejs>
<% layout('layouts/boilerplate')%>
<h1>Login</h1>
<form action="/register" method="POST" class="validated-form" novalidate>
  <div class="mb-3">
    <label class="form-label" for="username">Username</label>
    <input
      class="form-control"
      type="text"
      id="username"
      name="username"
      required
    />
    <div class="valid-feedback">Looks good!</div>
  </div>
  <div class="mb-3">
    <label class="form-label" for="password">Password</label>
    <input
      class="form-control"
      type="password"
      id="password"
      name="password"
      required
    />
    <div class="valid-feedback">Looks good!</div>
  </div>
  <button class="btn btn-success">Login</button>
</form>

등록되지 않은 유저정보 입력시

올바른 유저정보로 로그인 시


7) isLoggedIn 미들웨어

Passport 의 Helper 메소드 이용 (isAuthenticated( ))

  • 세션을 이용해 고유의 정보 저장. (serializeUser, deserializeUser: 세션에서 정보를 어떻게 저장하고 가져오는지 결정)

campgrounds.js

  • 로그인 되어었지 않을시 새로운 캠핑장 생성 불가 코드


로그인 후 새로운 캠핑장 생성 하기


로그인 확인 여부 미들웨어 생성

<campgournds.js>

미들웨어 호출

const { isLoggedIn } = require('../middleware');


8) 로그아웃 추가하기

passport (logout)

  • 잘못된 호출

네비게이션 바에 로그인,회원가입,로그아웃 추가하기

<navbar.ejs>

<nav class="navbar sticky-top navbar-expand-lg navbar-dark bg-dark">
  <div class="container-fluid">
    <a class="navbar-brand" href="#">YelpCamp</a>
    <button
      class="navbar-toggler"
      type="button"
      data-bs-toggle="collapse"
      data-bs-target="#navbarNavAltMarkup"
      aria-controls="navbarNavAltMarkup"
      aria-expanded="false"
      aria-label="Toggle navigation"
    >
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
      <div class="navbar-nav">
        <a class="nav-link" href="/">Home</a>
        <a class="nav-link" href="/campgrounds">Campgrounds</a>
        <a class="nav-link" href="/campgrounds/new">New Campground</a>
      </div>
      <div class="navbar-nav m-auto">
        <a class="nav-link" href="/login">Login</a>
        <a class="nav-link" href="/register">Register</a>
        <a class="nav-link" href="/logout">Logout</a>
      </div>
    </div>
  </div>
</nav>

9) currentUser 도우미

사용자의 객체/ID 같은 정보에 접근하기

  • req.user 이용시 자동으로 정보 저장.
  • 세션에 저장되어 있어도 세션을 찾아보지 않아도됨.
  • Passport에 의해 자동으로 세션에서 역직렬화된(deserialized) 정보가 req.user에 담기게됨.
  • 세션의 직렬화된(serialized) 사용자정보를 Passport가 역직렬화해서 req.user에 정보를 담음.


세션에 저장된 사용자 정보

  • Passport 를 사용했기에 가능한 req.user


로그인/비로그인 상황마다 네비게이션 바에 어떤 항목을 넣을건지에 대한 결정 (Login , Register, Logout)

  • currentUesr의 상황에 따라 달리 제공됨.

navbar.ejs 에 조건 추가하기

  • 로그인 안 했을 때: Login, Register 띄우기
  • 로그인 했을 때 : Logout만 띄우기.


10) 레지스터 경로 고정하기

회원가입 후 재 로그인 하지않고 로그인 상태를 유지하게끔 만들기.

  • req.login 사용 (새로운 사용자의 회원가입시 로그인 상태를 유지하게 만들어줌).
  • 다만 await 함수가 아니므로 매게변수로 err 를 받아야함.

새로운 회원가입

  • 로그인 상태가 유지됬다는 결과로 네비게이션 바에 Logout 만 뜨는걸 알 수 있음. (재로그인 불필요)


11) ReturnTo 명령어 특징

  • 사용자가 비로그인 상황에서는 캠핑장 추가/편집 혹은 리뷰 달기 등과 같은 행동을 했을 때 로그인이 되있지 않아서 로그인 화면으로 이동하게 된다.

  • 그리고 추후 로그인을 하게되면 "원래" 의도를 수행하기 위해 인덱스페이지가 아닌 기존에 클릭했던 홈페이지로 이동하게 만들기 위한것이다.


  • 미들웨어 내 세션 정보로 returnTo (다시 돌아갈 곳) 를 저장한다.

  • 세션의 정보를 알기위해 console.log(req.session)을 실행시 최초에 로그인은 안되었지만 시도했었던 경로를 알려준다.


  • 재로그인시 redirectUrl 변수를 통해 최초의 의도했던 페이지로 이동하게 되며 웹페이지 홈에서 로그인을 했을 수 도 있으니 '/campgrounds'도 추가한다.

  • 그리고 리다이렉트 성공시 세션에 저장된 redirectUrl정보는 삭제 한다
    (delete)

router.post('/login', passport.authenticate('local', { failureFlash: true, failureRedirect: '/login' }), (req, res) => {
    req.flash('success', 'welcome back!');
    const redirectUrl = req.session.returnTo || '/campgrounds';
    delete req.session.returnTo;
    res.redirect(redirectUrl);
})
profile
WILL is ALL

0개의 댓글