티스토리 뷰

Dev/JavaScript

[Node.js] Passport 모듈을 이용한 사용자 인증

꿈을 위해 잠을 잊은 그대에게 2018. 7. 21. 17:50

Passport 모듈을 이용한 사용자 인증을 진행해보겠습니다.




모듈 설치



http://www.passportjs.org/


passport 모듈에 관한 정보들을 담고 있는 웹사이트



Documentation -> Configure


Passport 모듈을 사용하기 위한 환경설정 가이드입니다.


모듈에 따른 설정 방법들이 잘 가이드 되어 있으니 참고하시면 됩니다.


var session = require('express-session');
var passport = require('passport')
var LocalStrategy = require('passport-local').Strategy;


모듈 선언


app.use(session({ // session 미들웨어
secret: '1234DSFs@adf1234!@#&asd',
resave: false,
saveUninitialized: true,
// store: new FileStore()
}));
app.use(passport.initialize()); // passport 초기화
app.use(passport.session()); // session을 사용


session 정보를 담습니다.

passport의 session 정보를 사용하기 이전에 session 정보를 갖고 있어야 하므로 코드 작성 시 우선 순위를 잘 염두하여야 합니다.


passport.use(new LocalStrategy( // 로컬 전략
function (username, password, done) { // 콜백함수
var uname = username;
var pwd = password;
for (var i = 0; i < users.length; i++) {
var user = users[i];

if (uname === user.username) { // 사용자 존재 유무 검사
return hasher({ password: pwd, salt: user.salt }, function (err, pass, salt, hash) {
if (hash === user.password) { // 사용자가 있다면
console.log('LocalStrategy', user);
done(null, user); // 로그인 성공
// req.session.displayName = user.displayName;
// req.session.save(function () {
// res.redirect('/welcome');
// })
} else { // 사용자가 없다면
done(null, false); // 로그인 실패
// res.send('Who are you? <a href="/auth/login">login</a>');
}
});
}
}
done(null, false);
// res.send('Who are you? <a href="/auth/login">login</a>');
}
));


Passport의 LocalStrategy (로컬 전략)을 사용함으로써 사용자 인증에 대한 전략을 만듭니다.


app.post('/auth/login',
passport.authenticate( // 미들웨어를 받아서 인증작업을 처리
'local', // 로컬 방식
{
successRedirect: '/welcome', // 로그인 성공
failureRedirect: '/auth/login', // 로그인 실패
failureFlash: false
}
)
);


port를 통한 로그인 작업입니다. 전략에 따른 인증작업을 처리합니다.


passport.serializeUser(function (user, done) {
console.log('serializeUser', user);
done(null, user.username);
});

passport.deserializeUser(function (id, done) {
console.log('deserializeUser', id);
for (var i = 0; i < users.length; i++) {
var user = users[i];
if (user.username === id) {
return done(null, user);
}
}
});



유저가 로그인 되었을 때, 로그아웃 되었을 때 초기화와 비초기화 작업을 사용하여 처리를 할 수 있습니다.


app.get('/welcome', function (req, res) {
if (req.user && req.user.displayName) { // passport로 부터 받은 유저 객체가 사용자 정보와 같으면
res.send(`
<h1>Hello, ${req.user.displayName}</h1>
<a href="/auth/logout">logout</a>
`);
} else {
res.send(`
<h1>Welcome</h1>
<ul>
<li><a href="/auth/login">Login</a></li>
<li><a href="/auth/register">Register</a></li>
</ul>
`);
}
});


사용자 인증 방법은 req 객체를 통한 기존 사용자 정보와 새로운 유저 객체를 비교하여 처리합니다.


app.get('/auth/logout', function (req, res) {
req.logout();
req.session.save(function () {
res.redirect('/welcome');
});
});


로그아웃 실행 시 req 객체를 통한 logout 메소드를 호출하여 간편하게 처리할 수 있습니다.




app.post('/auth/register', function (req, res) {
hasher({ password: req.body.password }, function (err, pass, salt, hash) {
var user = {
username: req.body.username,
password: hash,
salt: salt,
displayName: req.body.displayName
};
users.push(user);
req.login(user, function (err) {
req.session.save(function () {
res.redirect('/welcome');
});
});
});
});


등록 후 바로 로그인 처리가 가능하도록 합니다.



전체 코드


var express = require('express');
var session = require('express-session');
// var FileStore = require('session-file-store')(session);
var bodyParser = require('body-parser');
var bkfd2Password = require("pbkdf2-password");
var passport = require('passport')
var LocalStrategy = require('passport-local').Strategy;
var hasher = bkfd2Password();

var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({ // session 미들웨어
secret: '1234DSFs@adf1234!@#&asd',
resave: false,
saveUninitialized: true,
// store: new FileStore()
}));
app.use(passport.initialize()); // passport 초기화
app.use(passport.session()); // session을 사용
app.get('/count', function (req, res) {
if (req.session.count) {
req.session.count++;
} else {
req.session.count = 1;
}
res.send('count : ' + req.session.count);
});
app.get('/auth/logout', function (req, res) {
req.logout();
req.session.save(function () {
res.redirect('/welcome');
});
});
app.get('/welcome', function (req, res) {
if (req.user && req.user.displayName) { // passport로 부터 받은 유저 객체가 사용자 정보와 같으면
res.send(`
<h1>Hello, ${req.user.displayName}</h1>
<a href="/auth/logout">logout</a>
`);
} else {
res.send(`
<h1>Welcome</h1>
<ul>
<li><a href="/auth/login">Login</a></li>
<li><a href="/auth/register">Register</a></li>
</ul>
`);
}
});
passport.serializeUser(function (user, done) {
console.log('serializeUser', user);
done(null, user.username);
});

passport.deserializeUser(function (id, done) {
console.log('deserializeUser', id);
for (var i = 0; i < users.length; i++) {
var user = users[i];
if (user.username === id) {
return done(null, user);
}
}
});
passport.use(new LocalStrategy( // 로컬 전략
function (username, password, done) { // 콜백함수
var uname = username;
var pwd = password;
for (var i = 0; i < users.length; i++) {
var user = users[i];

if (uname === user.username) { // 사용자 존재 유무 검사
return hasher({ password: pwd, salt: user.salt }, function (err, pass, salt, hash) {
if (hash === user.password) { // 사용자가 있다면
console.log('LocalStrategy', user);
done(null, user); // 로그인 성공
// req.session.displayName = user.displayName;
// req.session.save(function () {
// res.redirect('/welcome');
// })
} else { // 사용자가 없다면
done(null, false); // 로그인 실패
// res.send('Who are you? <a href="/auth/login">login</a>');
}
});
}
}
done(null, false);
// res.send('Who are you? <a href="/auth/login">login</a>');
}
));
app.post('/auth/login',
passport.authenticate( // 미들웨어를 받아서 인증작업을 처리
'local', // 로컬 방식
{
successRedirect: '/welcome', // 로그인 성공
failureRedirect: '/auth/login', // 로그인 실패
failureFlash: false
}
)
);
// app.post('/auth/login', function(req, res){
// var uname = req.body.username;
// var pwd = req.body.password;
// for(var i=0; i<users.length; i++){
// var user = users[i];
// if(uname === user.username) {
// return hasher({password:pwd, salt:user.salt}, function(err, pass, salt, hash){
// if(hash === user.password){
// req.session.displayName = user.displayName;
// req.session.save(function(){
// res.redirect('/welcome');
// })
// } else {
// res.send('Who are you? <a href="/auth/login">login</a>');
// }
// });
// }
// }
// res.send('Who are you? <a href="/auth/login">login</a>');
// });
app.get('/auth/login', function (req, res) {
var output = `
<h1>Login</h1>
<form action="/auth/login" method="post">
<p>
<input type="text" name="username" placeholder="username">
</p>
<p>
<input type="password" name="password" placeholder="password">
</p>
<p>
<input type="submit">
</p>
</form>
`;

res.send(output);
});

var users = [
{
username: 'swk',
password: 'hcBng2j2P7vFsJ0a0g4P5owVO+mI0Wujtd6q7yivciHvm1RJobUNc1Zj/leg/rQXBkSuFxK0iU4Y2j+wLByYtq1Qm1EWDH9hyrbiwgH7g99l8LDT4jx0eaDwP84XHaPp6mOWmzsVu+XwVocIXSzu3QdmHLqJZzPdSIlqT8su1mQ=',
salt: 'G34WguBAJgbPPi6BtQ/H1l+38dRq9Vyanv/orzkqllTUctKg4cLC14sNKX4IigZ88s90b/WdNMcxIL/4qGrakg==',
displayName: 'swk'
},
];
app.post('/auth/register', function (req, res) {
hasher({ password: req.body.password }, function (err, pass, salt, hash) {
var user = {
username: req.body.username,
password: hash,
salt: salt,
displayName: req.body.displayName
};
users.push(user);
req.login(user, function (err) {
req.session.save(function () {
res.redirect('/welcome');
});
});
});
});
app.get('/auth/register', function (req, res) {
var output = `
<h1>Register</h1>
<form action="/auth/register" method="post">
<p>
<input type="text" name="username" placeholder="username">
</p>
<p>
<input type="password" name="password" placeholder="password">
</p>
<p>
<input type="text" name="displayName" placeholder="displayName">
</p>
<p>
<input type="submit">
</p>
</form>
`;
res.send(output);
});
app.listen(3003, function () {
console.log('Connected 3003 port!!!');
});


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크