Notice
Recent Posts
Recent Comments
Link
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

공부하자

[Node] 로그인 구현하기(3) - passport.js 사용하기 본문

공부/Node.js

[Node] 로그인 구현하기(3) - passport.js 사용하기

strongstar 2018. 5. 14. 19:35

로그인 구현하기(1)에서는 사용자가 입력한 값을 DB(mysql)에 저장된 값과 비교했습니다.

로그인 구현하기(2)에서는 로그인한 사용자의 정보를 세션에 저장했습니다.

로그인 구현하기(3)에서는 passport-local 인증을 사용합니다.


예제를 위한 예제입니다.

이대로 쓰시면 안돼요.




- app_passport.js


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
var express = require('express');
var mysql = require('mysql');
var session = require('express-session');
var MySQLStore = require('express-mysql-session')(session);
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var bodyParser = require('body-parser');
var ejs = require('ejs');
var crypto = require('crypto');
var dbConfig = require('./dbConfig');
 
var app = express();
var dbOptions = dbConfig;
var conn = mysql.createConnection(dbOptions);
conn.connect();
app.set('view engine''ejs');
app.set('views''./views');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
    secret: '!@#$%^&*',
    store: new MySQLStore(dbOptions),
    resave: false,
    saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
 
passport.use(new LocalStrategy(
  function(username, password, done) {
    var sql = 'SELECT * FROM user WHERE id=?';
    conn.query(sql, [username], function(err, results){
      if(err)
        return done(err);
      if(!results[0])
        return done('please check your id.');
 
      var user = results[0];
      crypto.pbkdf2(password, user.salt, 10000064'sha512'function(err, derivedKey){
        if(err)
          return done(err);
 
        if(derivedKey.toString('hex'=== user.password)
          return done(null, user);
        else
          return done('please check your password.');
      });//pbkdf2
    });//query
  }
));
passport.serializeUser(function(user, done) {
  done(null, user.id);
});
 passport.deserializeUser(function(id, done) {
  var sql = 'SELECT * FROM user WHERE id=?';
  conn.query(sql, [id], function(err, results){
    if(err)
      return done(err, false);
    if(!results[0])
      return done(err, false);
 
    return done(null, results[0]);
  });
});
 
app.get('/'function (req, res) {
  if(!req.user)
    res.redirect('/login');
  else
    res.redirect('/welcome');
});
app.get('/login'function(req, res){
  if(!req.user)
    res.render('login', {message:'input your id and password.'});
  else
    res.redirect('/welcome');
});
app.get('/welcome'function(req, res){
  if(!req.user)
    return res.redirect('/login');
  else
    res.render('welcome', {name:req.user.name});
});
app.get('/logout'function(req, res){
  req.logout();
  res.redirect('/');
});
 
app.post('/login',
  passport.authenticate(
    'local',
    {
      successRedirect: '/welcome',
      failureRedirect: '/login',
      failureFlash: false
    })
);
 
app.listen(3000function () {
  console.log('Example app listening on port 3000!');
});
 
cs


처음 보면 사용법이 한눈에 잘 안들어옵니다. 천천히 보셔야 하는데요.

serializeUser의 user.id 가 deserializeUser 의 id로 넘어갑니다.

이때 꼭 id를 인자로 넘겨야하는 것은 아니고, user_key 등 유니크한 값이 있다면 그걸 넘겨줘도 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function (err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(nullfalse, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(nullfalse, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));
passport.serializeUser(function(user, done) {
  done(null, user.id);
});
passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});
cs


- views/login.ejs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Login Page</title>
  </head>
  <body>
    <h1><%= message %></h1>
    <form action="/login" method="post">
      <input type="text" name="username" placeholder="id" /><br />
      <input type="password" name="password" placeholder="password" /><br />
      <input type="submit" />
    </form>
  </body>
</html>
 
cs


- views/welcome.ejs


1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Welcome Page</title>
  </head>
  <body>
    <h1>Hello, <%= name %></h1>
    <h2><a href="/logout">logout</a></h2>
  </body>
</html>
 
cs




* 참고

[공식Doc] passport.js (링크)

[npm] passport (링크)


예제 코드 다운받기 (링크)

Comments