Node ch.17 _ Ajax 이용하여 passport 로그인 구현
회원가입과 유사한, 로그인 로직에 필요한 HTML을 구성하고 필요한 Router설정을 할 수 있다.
-
router/index.js 에 login 라우터 추가
var express = require('express') var app = express() var router = express.Router() var path = require('path') var main = require('./main/main') var email = require('./email/email') var join = require('./join/index') var login = require('./login/index') router.get('/', function(req,res){ console.log('indexjs . path loaded'); res.sendFile(path.join(__dirname + "/../public/main.html")) }); router.use('/main', main) router.use('/email', email) router.use('/join', join) router.use('/login', login) module.exports = router;
-
router/login/index.js 경로&파일 생성 후 아래와 같이 입력 (join과 비슷)
var express = require('express') var app = express() var router = express.Router() var path = require('path') var mysql = require('mysql') var passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; // DATABASE SETTING (Google Cloud SQL) var connection = mysql.createConnection({ host : '35.184.164.59', port : 3306, user : 'root', password : 'root', database : 'jsman' }); connection.connect(); router.get('/', function(req,res){ var msg; var errMsg = req.flash('error'); if(errMsg) msg = errMsg; res.render('login.ejs', {'message' : msg}); }) //passport.serialize passport.serializeUser(function(user, done) { console.log('passport session save : ', user.id) done(null, user.id); }); passport.deserializeUser(function(id, done) { console.log('passport session get id: ', id) done(null, id); }); //세션값을 뽑아서 db에 전달 passport.use('local-login', new LocalStrategy({ usernameField: 'email', //default 속성값 passwordField: 'password', //default 속성값 passReqToCallback: true }, function (req, email, password, done) { var query = connection.query('select * from user where email=?', [email], function(err,rows){ if(err) return done(err); if(rows.length){ console.log('existed user') return done(null, false, {message : 'Your email is already used'}) } else { var sql = {email: email, password:password}; var query = connection.query('insert into user set ?', sql, function(err,rows) { if(err) throw err return done(null, {'email' : email, 'id' : rows.insertId}); }) } }) } )); router.post('/', passport.authenticate('local-join', { successRedirect: '/main', failureRedirect: '/join', failureFlash: true }) ) module.exports = router;
-
views/loing.ejs 파일 생성
<html> <head> <meta charset="utf-8"> <title>email form</title> </head> <body> <form action="/email/form" method="post"> email : <input type="text" name="email"> <br/> passwd : <input type="password" name="password"> <br/> </form> <button class="ajaxsend">login</button> <div class="result"></div> <script> document.querySelector('.ajaxsend').addEventListener('click', function() { var email = document.getElementsByName('email')[0].value; var password = document.getElementsByName('password')[0].value; sendAjax('http://localhost:3000/email/ajax',{'email' : email, 'password' : password}); }) function sendAjax(url, data){ var data = {'email' : data}; data = JSON.stringify(data); var xhr = new XMLHttpRequest(); xhr.open('POST', url); xhr.setRequestHeader('Content-Type', "application/json"); //서버로 json형태로 보낸다는걸 나타내주기위해 xhr.send(data); xhr.addEventListener('load', function(){ //console.log(xhr, responseText); var result = JSON.parse(xhr.responseText); var resultDiv = document.querySelector(".result"); if(result.result !== "ok") resultDiv.innerHTML = "Your email is not found" else resultDiv.innerHTML = result.name; }); } </script> </body> </html>
-
여기까지의 결과확인
이 상태에서 post 로 요청을 보내면 /router/login/index.js의 router.post() 에서 처리를 해주는데,
ajax로 요청을 받았으므로 passport에서 제공하는 custom callback을 이용하여 json으로 응답을 처리할 수 있다
-
Custom callback
/router/login/index.js 에 Custom callback 으로 post 수정
var express = require('express') var app = express() var router = express.Router() var path = require('path') var mysql = require('mysql') var passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; // DATABASE SETTING (Google Cloud SQL) var connection = mysql.createConnection({ host : '35.184.164.59', port : 3306, user : 'root', password : 'root', database : 'jsman' }); connection.connect(); router.get('/', function(req,res){ var msg; var errMsg = req.flash('error'); if(errMsg) msg = errMsg; res.render('login.ejs', {'message' : msg}); }) //passport.serialize passport.serializeUser(function(user, done) { console.log('passport session save : ', user.id) done(null, user.id); }); passport.deserializeUser(function(id, done) { console.log('passport session get id: ', id) done(null, id); }); //세션값을 뽑아서 db에 전달 passport.use('local-login', new LocalStrategy({ usernameField: 'email', //default 속성값 passwordField: 'password', //default 속성값 passReqToCallback: true }, function (req, email, password, done) { console.log(1); var query = connection.query('select * from user where email=?', [email], function(err,rows){ if(err) return done(err); if(rows.length){ console.log('existed user') return done(null, {'email' : email, 'id' : rows[0].UID}) } else { return done(null, false, {'message' : 'Your login info is not found.'}) } }) } )); // router.post('/', passport.authenticate('local-join', { // successRedirect: '/main', // failureRedirect: '/join', // failureFlash: true }) // ) // Custom callback router.post('/', function (req, res, next) { passport.authenticate('local-login', function (err, user, info) { if(err) res.status(500).json(err); // 에러를 json으로 응답 주기 if(!user) return res.status(401).json(info.message); // 유저가 없을 때에도 json으로 응답 주기 req.logIn(user, function (err) { if(err) {return next(err); } return res.json(user); }); })(req, res, next); }) module.exports = router;
-
login.ejs 수정
<html> <head> <meta charset="utf-8"> <title>email form</title> </head> <body> <form action="/email/form" method="post"> email : <input type="text" name="email"> <br/> passwd : <input type="password" name="password"> <br/> </form> <button class="ajaxsend">login</button> <div class="result"></div> <script> document.querySelector('.ajaxsend').addEventListener('click', function() { var email = document.getElementsByName('email')[0].value; var password = document.getElementsByName('password')[0].value; sendAjax('http://localhost:3000/login',{'email' : email, 'password' : password}); }) function sendAjax(url, data){ var data = {'email' : data}; data = JSON.stringify(data); var xhr = new XMLHttpRequest(); xhr.open('POST', url); xhr.setRequestHeader('Content-Type', "application/json"); //서버로 json형태로 보낸다는걸 나타내주기위해 xhr.send(data); xhr.addEventListener('load', function(){ //console.log(xhr, responseText); var result = JSON.parse(xhr.responseText); var resultDiv = document.querySelector(".result"); if(result.email) resultDiv.innerHTML = "Welcome, " + result.email + "!" else resultDiv.innerHTML = result; }); } </script> </body> </html>
-
여기까지 수정 완료하고 email과 password 항목 써주면,
DB에 없는 email 입력 시 “Your login info is not found.” 출력
DB에 있는 email 입력 시 “Welcome XXX@XXX.XXX !” 출력
되야하는데 오류남 …
401 (Unauthorized) "Missing credentials"
이러한 오류가..힝입니다….