노드JS [Express]

[다중 사용자] 노드 JS 다중 사용자 + 패스워드 암호화 정리 글

훈츠 2020. 7. 4. 20:25
반응형

 

 

 

안녕하세요. 훈츠입니다. 이 정리글은 생활코딩 예제를 기반으로 작성하였습니다. 패스포트 JS 다음예제인 다중 사용자를 학습 및 실습해보고 정리한 글입니다. 다시 한번 이고잉님 이하 개발자분들께 감사를 표합니다. 


목 차

  • lowdb 데이터 베이스 추가 

  • 패스워드 암호화를 위한 bcrypt 미들웨어 추가  

  • 회원가입 UI 만들기 

  • 회원정보 저장 into 인증정보 저장

  • 로그인 구현 

  • 접근제어 - 글쓰기 (Create)

  • 접근제어 - 글읽기 (Read)

  • 접근제어 - 글수정 (Update)

  • 접근제어 - 글삭제 (Delete)

  • bcrypt - 비밀번호 암호화 

  • 코드 공유


lowdb 데이터 베이스 추가 

JSON 형태로 데이터를 저장하는 아주아주 가벼운 데이터베이스 lowdb 입니다. 사용해본 경험으로는 그다지 어렵지않고 가볍게 사용하기에 좋은것 같습니다. 다음 데이터 베이스를 적용 했습니다. 

 

사이트 : https://github.com/typicode/lowdb

typicode/lowdb

⚡️ lowdb is a small local JSON database powered by Lodash (supports Node, Electron and the browser) - typicode/lowdb

github.com

설치법 

npm install -s lowdb

 

샘플 코드 

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
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
 
const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync')
 
const adapter = new FileSync('db.json')
const db = low(adapter)
 
// Set some defaults (required if your JSON file is empty)
db.defaults({ posts: [], user: {}, count: 0 })
  .write()
 
// Add a post
db.get('posts')
  .push({ id: 1, title: 'lowdb is awesome'})
  .write()
 
// Set a user using Lodash shorthand syntax
db.set('user.name''typicode')
  .write()
  
// Increment count
db.update('count', n => n + 1)
  .write()
 
 
cs

패스워드 암호화를 위한 bcrypt 미들웨어 추가

비밀번호를 해시값으로 변조할수있고, 그 변조된값과 일반 패스워드와 비교하는기능을 제공합니다. 패스워드를 평문으로 데이터베이스 혹은 파일에 저장하는것은 굉장히 굉장히 위험하고 잘못된 방식 입니다. 이 라이브러리를 이용하면 손쉽게 비밀번호 암호화가 가능합니다.

사이트 : https://www.npmjs.com/package/bcrypt

bcrypt

A bcrypt library for NodeJS.

www.npmjs.com

 

설치법 

npm install -s bcrypt

 

샘플 코드 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
 
const bcrypt = require('bcrypt');
const saltRounds = 10;  //해킹 시도시 재시작 못하도록 하는값, 커질수록 해킹이 어려워짐. 
const myPlaintextPassword = '1111'//패스워드 저장
const someOtherPlaintextPassword = '1112'//테스트위한 패스워드 저장 
 
bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) {
    // 이곳에서 암호화된 hash 값을 DB에 저장 하세요.
});
 
// Load hash from your password DB.
bcrypt.compare(myPlaintextPassword, hash, function(err, result) {
    // 원래 넣었떤 패스워드와 저장되어있는 hash 값을 비교 합니다.     
    // result == true 결과값은 true 입니다. 
});
bcrypt.compare(someOtherPlaintextPassword, hash, function(err, result) {
    // 다른 패스워드와 저장되어있는 hash 값을 비교 합니다. 
    // result == false 결과값은 false 입니다. 
});
 
 
cs

회원가입 UI 만들기 

코드에 대한 설명은 하지 않도록 하겠습니다.

 

파일 수정 및 추가 

 1. ../lib/auth.js 수정

 2. ../lib/template.js 수정 

 3. ../routes/auth.js 수정 

 

1. ../lib/auth.js 수정 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
 
module.exports = {
    IsOwner : function (request,response){
    if(request.user){   //유저 유무에 따라 로그인 및 로그아웃을 판단 합니다. 
        return true;
    } else {
        return false;
    }
},
    StatusUI : function (request,response){
    var authStatusUI= `<a href="/auth/login">login</a> | <a href="/auth/register">register</a>//register 부분 
    if(this.IsOwner(request,response)){
        console.log(request.user.nickname);    
        authStatusUI= `${request.user.nickname} | <a href="/auth/logout">logout</a>`
    } 
        return authStatusUI;
    }
}
 
cs

 

2. ../lib/template.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
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
 
module.exports = {
    html : function (title,list,body, control, authStatusUI=`<a href="/auth/login">login</a> | <a href="/auth/register">register</a>`){
        return `
        <!doctype html>
        <html>
        <head>
        <title>WEB1 -${title}</title>
        <meta charset="utf-8">
        </head>
        <body>
        ${authStatusUI}
        <h1><a href="/">WEB</a></h1>
        ${list}
        ${control}
        ${body}
        </body>
        </html>
        `;
    }, 
    list : function (filelist){
        var list = `<ul>`;
        var i = 0;
        while(i < filelist.length){
            list = list + `<li><a href="/topic/${filelist[i].id}">${filelist[i].title}</a></li>`;                        
            i = i+ 1;
        }
        list = list +`</ul>`;
        return list;
    }
}
 
 
 
cs

3. ../routes/auth.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
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
 
//REGISTER 
router.get('/register', function(request, response){
    //플래시 메시지 request.flash 로 들어옵니다. 
    var fmsg = request.flash();
    console.log('flash',fmsg);
    var feedback =''
    if(fmsg.error){
       feedback = fmsg.error[0]
    }
    
   var filelist = request.filelist;
   var title = 'WEB - register';
   var list = template.list(filelist)
   var html = template.html(title,list,`
   <div style="color:red">${feedback}<div>
   <form action="/auth/register_process"
       method="POST">
       <p><input type="text" name="email" placeholder="email"></p>
       <p><input type="password" name="password" placeholder="password"></p>
       <p><input type="password" name="password2" placeholder="password2"></p>
       <p><input type="text" name="nickname" placeholder="nickname"></p>
       <p><input type="submit" vlaue="register"></p>
 
       </form>
   
   `,'');
   response.send(html);
});
 
 
 
 
cs

회원정보 저장 into 세션

기존에 file로 저장 하던 부분을 lowdb를 설치하고 JSON 파일안에 데이터를 저장 하도록 변경 하였습니다. 

 

순서

1. lowdb 설치 및 사용설정 (이전 글 참조) 

2. shortid 설치 및 사용설정 

3. main.js 수정 

4. auth.js - register_process 수정 / 세션에 저장 

 

1. lowdb 설치 및 사용설정 (이전 글 참조) 

1
2
3
4
5
6
7
8
9
10
11
12
13
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
 
const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync');
const adapter = new FileSync('db.json')
const db = low(adapter)
 
db.defaults({users:[], topics:[], hashs:''}).write();
 
module.exports = db; //외부에서 사용 가능하도록 
 
 
 
cs

2. shortid 설치 및 사용설정 

 npm install -s shortid

1
2
3
4
5
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
 
const shortid = require('shortid');
var id = shortid.generate(); //자동으로 유니크한 id 값을 생성합니다. 
 
cs

3. main.js 수정 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
 
//미들웨어 만들어 사용하기 
//타이틀 리스트 
app.get('*',function(req,res, next){
    req.filelist = db.get('topics').value();
    next();
    
    //기존 파일 리스트 읽는코드 
    /* fs.readdir('./data', function(err, filelist){
        req.filelist = filelist;
        next();
    }); */
});
 
 
cs

4. auth.js - register_process 수정 / 세션에 저장 됩니다. 

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
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
 
//REGISTER PROCESS Method is POST 
router.post('/register_process', function (request, response) {
    var post = request.body;
    var email = post.email;
    var password = post.password;
    var password2 = post.password2;
    var nickname = post.nickname;
    //코드 생략~~
    const user  = {
                id : shortid.generate(), //short id 생성 
                email:email,
                password:password,
                nickname:nickname
            }
            // lowDB 에 저장 
            db.get('users').push(user).write();
 
            //로그인 세션에 넘겨준 데이터가 저장됩니다.     
            request.login(user, function(err){
                console.log('login suecess')
                response.redirect('/');
            })
        });  
            
    }
    
}); 
    return router;
}
 
cs

로그인 구현 

패스포트.js 파일을 수정합니다. 기존에 authData를 세션에 저장되어있는 user 객체를 이용하여 id 와 password를 검증합니다.

 

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
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
 
module.exports = function(app){
const db = require('../lib/lowdb')
 
//패스포트 로컬 전략 
var passport = require('passport'), 
    LocalStrategy = require('passport-local').Strategy;
 
//passport session 사용 
app.use(passport.initialize());
app.use(passport.session());
 
 
//패스포트 사용 
passport.use(new LocalStrategy(
    //사용자가 필드를 변경시키고 싶으면 아래처럼 추가 합니다. 
    {
        usernameField: 'email',
        passwordField: 'password'
    },
    function(email, password, done) {
        console.log('LocalStrategy ' + email, password)
        user = db.get('users').find({email:email}).value();
        if(email === user.email){
            console.log('1');
                if(password === user.password){
                    console.log('2');
                    return done(null, user); //아이디와 비번이 일치할때, done 함수로 유저데이터를 넣어주면 session에 등록됩니다. 
                }else{
                    console.log('3');
                    return done(nullfalse, { message: 'Incorrect password.' });      
                }
            });    
        } else {
            console.log('4');
            return done(nullfalse, { message: 'Incorrect username.' });
        }
    }
  ));
 
//Passport 로그인이 성공되면, 그곳에서 입력한 데이터가 이곳에 콜백의 유저로 넘어 옵니다. 
passport.serializeUser(function(user, done) {
    console.log('serializeUser :' , user.id);
    done(null, user.id);
  });
 
//한번 통신하고 나면,웹이 리로드될때마다 이곳이 호출되어서 이곳에서 DB의 유저값을가져와 비교합니다.   
//심플한 테스트를 위해,db 에 있는값이 아닌 위의 값을 넣어줍니다. 
passport.deserializeUser(function(id, done) {
    
    var user = db.get('users').find({id:id}).value();
    console.log('deserializeUser :',id,user);
    done(null, user);
   
});
    return passport;
}
 
cs

접근제어 - 글쓰기 (Create)

글쓰기 할때, 로그인한 당사자의 id 값을 저장 합니다. 이후에 읽기, 수정 그리고 삭제 할때 확인용으로 id 값이 필요 합니다. 

 

router.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
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
//이전 코드생략 
//CREATE PROCESS Method is POST 
router.post('/create_process', function (request, response) {
       var post = request.body;
       var title = post.title;
       var description = post.description;
       var id = shortid.generate();
 
        //글제목 및 내용을 LOWDB에 합니다. 
       db.get('topics').push({id:id,title:title,description:description,user_id:request.user.id}).write();
 
        //shortid 로 자동생성된 id 값으로 페이지를 리다이렉션 합니다. 
       response.redirect(`/topic/${id}`);
       
}); 
 
//WEB PAGE load 
router.get('/:pageId', function(request, response, next){
    //형식은 'user내가 치는거대로+ Id' ex page를 쳤다면 pageId
    //pageId 에 들어오는 값은 : request.params.pageId 이 형식에 유의 하고, param 이라고 치지 않도록 유의!!!
    var topic = db.get('topics').find({id:request.params.pageId}).value();
    var user  = db.get('users').find({id:topic.user_id}).value();
 
    var filelist = request.filelist;  //main에 미들웨어로 넣어놓았음.
    var title = topic.title;
    var descriton = topic.description;
    var writer = user.nickname;      //글쓴이를 표현 해줍니다. 
 
    var create = loginCheckUI('create','','',request,response);    
    var update = loginCheckUI('update',topic,'',request,response);
    var deletes = loginCheckUI('deletes',topic,'',request,response);
 
    var list = template.list(filelist)
    var html = template.html(title,list,
        `<h2>${title}</h2>${descriton}<br>edit by ${writer}`,
        
        `${create}
            ${update}
            ${deletes}
        `,
        auth.StatusUI(request,response)
        );
    response.send(html);
    
});
 
 
 
 
 
cs

접근제어 - 글읽기 (Read)

적은 글을 읽기 위해서는 기존 readFile 함수를 모두 lowdb 의 get 함수로 바꿔서 읽어 줘야 합니다. 다음과 같은 부분을 수정 합니다. main.js 파일리스트를 넣어주는 미들웨어 부분은 이전에 변경 해두었으니, 위쪽에서 확인해보세요. 

 

1. template.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
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
module.exports = {
    html : function (title,list,body, control, authStatusUI=`<a href="/auth/login">login</a> | <a href="/auth/register">register</a>`){
        return `
        <!doctype html>
        <html>
        <head>
        <title>WEB1 -${title}</title>
        <meta charset="utf-8">
        </head>
        <body>
        ${authStatusUI}
        <h1><a href="/">WEB</a></h1>
        ${list}
        ${control}
        ${body}
        </body>
        </html>
        `;
    }, 
    list : function (filelist){
        var list = `<ul>`;
        var i = 0;
        while(i < filelist.length){
            list = list + `<li><a href="/topic/${filelist[i].id}">${filelist[i].title}</a></li>`; //이부분 수정                       
            i = i+ 1;
        }
        list = list +`</ul>`;
        return list;
    }
}
 
 
cs

접근제어 - 글수정 (Update)

router.js 에 update 부분과 update_process 부분을 수정 합니다. 

 

router.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
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
//UPDATE get
router.get('/update/:pageId', function(request, response){
            
    var topic = db.get('topics').find({id:request.params.pageId}).value(); //topic 정보 가져오기 
    var title = topic.title; //topic 에 title 
    var description = topic.description; //topic 에 description
    var filelist = request.filelist; //main에 미들웨어에 filelist 정보 가져오기
    
    var list = template.list(filelist)
    var html = template.html(title,list,
        `
        <form action="/topic/update_process" method="post">
            <input type="hidden" name="id" value="${topic.id}">
        <p>
            <input type="text" name="title" placeholder="title" value="${title}">
        </p>
        <p>
            <textarea name="description" placeholder="description">${description}</textarea>
        </p>
        <p>
            <input type="submit">
        </p>
        </form>
        `,
        `
        <a href="/topic/create">create</a> 
        <a href="/topic/update/${topic.id}">update</a>
        `
        ,
        auth.StatusUI(request,response)
    );
    response.send(html);
    
});
 
//UPDATE PROCESS Method POST
router.post('/update_process', function(request, response){
    var post = request.body;
    var id = post.id  // update 에서 
 
    var title = post.title;
    var description = post.description;
    var topic = db.get('topics').find({id:id}).value();
 
    if(topic.user_id !== request.user.id){
        request.flash('error is not yours');
        response.redirect('/');
        return false;
    }
    db.get('topics').find({id:id}).assign({
        title:title, description:description
    }).write();
    response.redirect(`/topic/${topic.id}`);
 
});
 
 
cs

접근제어 - 글삭제 (Delete)

글을 삭제 하기위해서, delete process 와 글을 읽고 이동하는 부분에서 login check를 확인하는 펑션에 lowdb 에 있는 id값을 받을수 있도록  수정 했습니다.

 

router.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
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
//DELETE Methode is POST
router.post('/delete_process', function (request, response){
    var post = request.body;
    var id = post.id; //delete 로 부터 받은 id 값 
    var topic = db.get('topics').find({id:id}).value();
    if(topic.user_id !== request.user.id){
        response.redirect('/');
        return false;
    }
    db.get('topics').remove({id:id}).write();
    response.redirect('/');
 
}); 
 
//login 체크 펑션 
function loginCheckUI(mode,topic,descriton,request,response){
    
    if(mode === 'create'){
        if(auth.IsOwner(request,response)){
            return create = `<a href="/topic/create">create</a>`; 
        } else {return ''}
    }
    if(mode === 'update'){
        if(auth.IsOwner(request,response)){
            return update = `<a href="/topic/update/${topic.id}">update</a>`; //topic.id 로 변경
        } else {return ''}
    }
    if(mode === 'deletes'){
        if(auth.IsOwner(request,response)){
            return deletes = `<form action="/topic/delete_process" method="post">
                                <input type="hidden" name="id" value="${topic.id}"> //topic.id 로 변경
                                <input type="submit" value="delete">
                            </form>`;
        } else {return ''}
    }
}
//WEB PAGE load 
router.get('/:pageId', function(request, response, next){
    //형식은 'user내가 치는거대로+ Id' ex page를 쳤다면 pageId
    var topic = db.get('topics').find({id:request.params.pageId}).value();
    var user  = db.get('users').find({id:topic.user_id}).value();
 
    var filelist = request.filelist;  //main에 미들웨어로 넣어놓았음.
    var title = topic.title;
    var descriton = topic.description;
    var writer = user.nickname;
 
    var create = loginCheckUI('create','','',request,response);    
    var update = loginCheckUI('update',topic,'',request,response);
    var deletes = loginCheckUI('deletes',topic,'',request,response);
 
    var list = template.list(filelist)
    var html = template.html(title,list,
        `<h2>${title}</h2>${descriton}<br>edit by ${writer}`,
        
        `${create}
            ${update}
            ${deletes}
        `,
        auth.StatusUI(request,response)
        );
    response.send(html);
    
});
cs

bcrypt - 비밀번호 암호화 

bcrypt 설정과 사용법은 글의 처음을 참조하세요. 적용 내용만 업데이트 합니다. 

 

bcrypt 를 이용하여, password를 hash로 받고 lowdb에 저장합니다. 

 

auth.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
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
const bcrypt = require('bcrypt');
const saltRounds = 10;
 
//REGISTER PROCESS Method is POST 
router.post('/register_process', function (request, response) {
    var post = request.body;
    var email = post.email;
    var password = post.password;
    var password2 = post.password2;
    var nickname = post.nickname;
     
    //코드 생략~    
    //bcrypt 를 이용하여, password를 넣으면 콜백으로 hash 값을 받습니다.
        bcrypt.hash(password, saltRounds, function(err, hash) {
            // Store hash in your password DB.
            const user  = {
                id : shortid.generate(),
                email:email,
                password:hash,  // 콜백의 hash 값을 user password 에 저장합니다. 
                nickname:nickname
            }
 
            db.get('users').push(user).write();  //lowdb 에 저장 합니다.   
            console.log('5');
            // passport 를 이용하여, 세션에 로그인 유저데이터 저장
            request.login(user, function(err){
                console.log('login suecess')
                response.redirect('/');
            })
        }); 
        
    }
    
}); 
 
cs

 

패스포트JS 에서 로그인 체크 하는 부분에서 hash 값으로 저장된 패스워드와 입력으로 들어온 패스워드를 bcrypt.compare 블럭을 이용하여 체크 합니다. 

 

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
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
 
module.exports = function(app){
const db = require('../lib/lowdb')
const bcrypt = require('bcrypt');
 
//패스포트 로컬 전략 
var passport = require('passport'), 
    LocalStrategy = require('passport-local').Strategy;
 
//passport session 사용 
app.use(passport.initialize());
app.use(passport.session());
 
 
//패스포트 사용 
passport.use(new LocalStrategy(
    //사용자가 필드를 변경시키고 싶으면 아래처럼 추가 합니다. 
    {
        usernameField: 'email',
        passwordField: 'password'
    },
    function(email, password, done) {
        console.log('LocalStrategy ' + email, password)
        user = db.get('users').find({email:email}).value();
        if(email === user.email){
 
            //bcrypt 의 compare 블럭으로 입력된 password 와 저장된 hash password를 비교 합니다. 
            bcrypt.compare(password, user.password, function(err, result) {
                if(result){
                    return done(null, user); //아이디와 비번이 일치할때, done 함수로 유저데이터를 넣어주면 session에 등록됩니다. 
                }else{
                    return done(nullfalse, { message: 'Incorrect password.' });      
                }
            });    
        } else {
            return done(nullfalse, { message: 'Incorrect username.' });
        }
    }
  ));
 
//Passport 로그인이 성공되면, 그곳에서 입력한 데이터가 이곳에 콜백의 유저로 넘어 옵니다. 
passport.serializeUser(function(user, done) {
    console.log('serializeUser :' , user.id);
    done(null, user.id);
  });
 
//한번 통신하고 나면,웹이 리로드될때마다 이곳이 호출되어서 이곳에서 DB의 유저값을가져와 비교합니다.   
//심플한 테스트를 위해,db 에 있는값이 아닌 위의 값을 넣어줍니다. 
passport.deserializeUser(function(id, done) {
    
    var user = db.get('users').find({id:id}).value();
    console.log('deserializeUser :',id,user);
    done(null, user);
   
});
    return passport;
}
 
 
cs

코드 공유

 

rain2002kr/LIFE_Passport.JS_Multi

생활코딩 다중사용자 예제코드입니다. . Contribute to rain2002kr/LIFE_Passport.JS_Multi development by creating an account on GitHub.

github.com