Node앱에 인증을 추가해줌.
Passport-Local Mongoose
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());
간단한 회원가입 폼 설정
<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>
폼 작성 후 유저로 등록하기. (POST)
폼 등록
동일한 유저네임 있을시.
{ failureFlash: true, failureRedirect:'/login'}
-> 입력된 비밀번호를 해쉬 처리하는 함수를 작성해 데이터베이스의 해시출력값과 비교해 사용자 인증과정에 사용.
<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>
등록되지 않은 유저정보 입력시
올바른 유저정보로 로그인 시
Passport 의 Helper 메소드 이용 (isAuthenticated( ))
campgrounds.js
로그인 후 새로운 캠핑장 생성 하기
로그인 확인 여부 미들웨어 생성
<campgournds.js>
미들웨어 호출
const { isLoggedIn } = require('../middleware');
passport (logout)
로그아웃은 콜백함수라 err를 매게변수로 받아줘야함.
버전 0.6.0 부터 바뀜
참고: https://stackoverflow.com/questions/72336177/error-reqlogout-requires-a-callback-function
잘된 호출
네비게이션 바에 로그인,회원가입,로그아웃 추가하기
<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>
사용자의 객체/ID 같은 정보에 접근하기
세션에 저장된 사용자 정보
로그인/비로그인 상황마다 네비게이션 바에 어떤 항목을 넣을건지에 대한 결정 (Login , Register, Logout)
navbar.ejs 에 조건 추가하기
회원가입 후 재 로그인 하지않고 로그인 상태를 유지하게끔 만들기.
새로운 회원가입
사용자가 비로그인 상황에서는 캠핑장 추가/편집 혹은 리뷰 달기 등과 같은 행동을 했을 때 로그인이 되있지 않아서 로그인 화면으로 이동하게 된다.
그리고 추후 로그인을 하게되면 "원래" 의도를 수행하기 위해 인덱스페이지가 아닌 기존에 클릭했던 홈페이지로 이동하게 만들기 위한것이다.
재로그인시 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);
})