node.js

node.js에서 passport를 이용한 로그인 구현하기

솜틀공장/ editor

  • 62 comments
  • 11,423 views
  • 2017년 5월 26일

들어가기 로그인 기능을 구현하기 위해서 신경써야 할 일이 한두가지가 아닙니다. 세션 설정에서부터 세션 유지와 회원관리를 위한 데이터베이스 관리까지 신경써야하니 초보자 또는 node.js를 처음 접하는 사람들도 헤매기 마련이죠. node.js에서는 고맙게도 이런 수고를 덜어주는 모듈들이 많이 존재하는데요, 이번에는 로그인을 쉽게 접근할 수 있는 passport를 이용해서 로그인을 구현해볼 예정입니다. passport는 많은 기능을 지원하는데, 무엇보다도 OAuth1.0과 OAuth2.0을 지원하기도 합니다. […]

들어가기


로그인 기능을 구현하기 위해서 신경써야 할 일이 한두가지가 아닙니다. 세션 설정에서부터 세션 유지와 회원관리를 위한 데이터베이스 관리까지 신경써야하니 초보자 또는 node.js를 처음 접하는 사람들도 헤매기 마련이죠.

node.js에서는 고맙게도 이런 수고를 덜어주는 모듈들이 많이 존재하는데요, 이번에는 로그인을 쉽게 접근할 수 있는 passport를 이용해서 로그인을 구현해볼 예정입니다.

passport는 많은 기능을 지원하는데, 무엇보다도 OAuth1.0과 OAuth2.0을 지원하기도 합니다.

저는 로그인 중에서 id와 password를 통해서 자체적으로 인증하는 Local login에 대해서 설명드리겠습니다.

해당 passport의 홈페이지를 살펴보면 크게 어려울 것 같지는 않는데, 기본적인 부분만을 다루고 있어서 사용자 보안 부분등에 대해서 조금 더 보충하고 mongoose와 연동해서 사용하는 방법에 대해서 알아보도록 하겠습니다.

 

지금부터 실습하는 내용의 프로그램의 구조는 express-generation에 의해서 생성된 구조를 기반으로 설명합니다.

express-generation의 내용이 궁금하신 분은 여기에서 살펴보시면 됩니다.

설치


로그인을 구현하기 위해서 몇 가지 모듈의 설치가 필요합니다.

  • passport
  • passport-local
  • mongoDB
  • mongoose
  • bcrypt-nodejs

passport는 passport의 core프로그램입니다. 우리는 로컬로그인을 하기로 했으니 그에 관련된 모듈인 passport-local까지 설치해야 합니다.

사용자 정보를 저장하기 위해서 mongoDB를 이용하는데, mongoose라는 mongoDB의 모듈을 이용해서 빠르고 쉽게 만들 예정입니다. 이 모듈을 사용하기 위해서는 mongoDB의 설치가 필수입니다. mongoDB는 해당 홈페이지에서 다운로드 할 수 있습니다.

mongoDB의 간단한 사용방법은 이 곳을 참고하시길 바랍니다.

node.js에서 mongoDB사용하기(mongodb-native)

node.js에서 mongoDB사용하기(mongoose)

 

bcryptjs는 암호화 모듈인데, 사용자 정보를 저장하고 password를 암호화 해주는데 사용할겁니다.

윈도우의 경우에는 파이썬을 설치해야 하는데,  홈페이지에서 다운로드 할 수 있습니다. 파이썬은 버전대별로 호환되지 않아서 최신버전이라고 그냥 설치하면 안되는 경우가 있습니다. 여기에서는 2.7버전으로 설치해서 실습하시면 됩니다.

 

passport 설치

>npm install passport --save

 

mongoose 설치

>npm install mongoose --save

 

암호화 모듈 설치

>npm install bcrypt-nodejs --save

 

 

프로그램 작성하기


제일 먼저 해야 할 부분은 passport의 설정값을 잡아야 합니다.

사실 이 세팅만 거의 하면 끝난다고 봐야죠.

 

로그인을 위한 form 작성

‘/views/index.ejs’ 파일에 다음의 내용을 추가합니다.

<form action="/login" method="post">
  <div>
    <label>Username:</label>
    <input type="text" name="username"/>
  </div>
  <div>
    <label>Password:</label>
    <input type="password" name="password"/>
  </div>
  <div>
    <input type="submit" value="Log In"/>
  </div>
</form>

submit버튼을 누르면 ‘/login’으로 post요청을 하게 했습니다.

 

app.js에서 passport 관련 세팅을 합니다.

일단 passport와 database관련 세팅을 간단하게 합니다.

var mongoose = require('mongoose');
var passport = require('passport');

mongoose.connect('localhost/test');
mongoose.Promise = global.Promise; 

var db = mongoose.connection;

//데이터베이스 접속 확인
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function (callback) {
    console.log("mongo DB connected...")
});
require('./config/passport')(passport);

app.use(passport.initialize());
app.use(passport.session()); //로그인 세션 유지

//플래시메세지를 사용한다면
var flash = require('connect-flash');
app.use(flash());

위의 코드를 app.js의 적당한 부분에 씁니다.

여기에서 필수설정을 하게 되고, 데이터베이스 연결설정 확인과 passport의 초기화, passport의 세션관리, 그리고 다음에 작성하게 될 passport의 구체적 세팅값을 넣을 곳을 마련하는 부분입니다.

또한 세션을 설정 해야 합니다. express에서는 편리하게 세션에 접근할 수 있는 모듈을 제공하고 있습니다.

> npm install express-session --save

express-session을 설치한 후에 세션 관련 설정을 위의 프로그램에 붙이면 됩니다.

var session = require('express-session');

app.use(session({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true
}));

 이 설정을 붙일때 주의해야 할 점은, 기본적으로 node.js가 비동기 방식이지만 app.use는 동기식으로 동작합니다. 따라서 어디에 붙이느냐에 따라서 프로그램이 실행되지 않을 수 있습니다.

 

config디렉토리를 생성하고 passport.js를 준비합니다. (/config/passport.js)

이제 이 passport.js에 관련 세팅을 할 예정입니다.

우리는 local에서 로그인을 확인하고 인증하는 시스템을 만들 예정인데, passport자체에는 로컬을 인증하는 로직이 없습니다. 그래서 이에 맞는 모듈을 설치해야 합니다. 왜 이렇게 만들었는지는 모르겠는데, 아마 코어프로그램과 다른 주변 프로그램을 분리해서 더 좋은 확장성을 제공하려는게 아닐까 생각합니다.

> npm install passport-local --save

위의 모듈의 설치가 완료 되었으면, 아래와 같이 코딩합니다.

var LocalStrategy = require('passport-local').Strategy
var User = require('../models/user');

module.exports = function(passport) {

    passport.serializeUser(function(user, done) {
        done(null, user.id);
    });
    passport.deserializeUser(function(id, done) {
        User.findById(id, function(err, user) {
            done(err, user);
        });
    });

    //프로그램 작성
};

전형적인 웹어플리케이션에서 사용자 인증에 사용된 자격증은 로그인 요청을 하는 동안에 전송되는데요. 인증에 성공하면 세션이 생성되고 사용자 브라우저의 쿠키에 의해서 유지가 됩니다.

이후의 요청은 자격증을 포함하지 않지만 특정한 쿠키는 세션을 구별합니다. 로그인의 세션을 지원하기 위해서 passport는 user 인스턴스에 세션을 serialize하고 세션으로 부터 deserialize하게 됩니다.

 

회원등록과 로그인 환경을 만듭니다.

회원등록을 만드는 방법은 어렵지 않습니다.

  • 데이터필드 지정
  • 입력된 사용자 데이터를 데이터베이스에 저장
  • 사용자가 입력한 암호는 암호화해서 저장

위와 같은 순서로 진행하면 됩니다. 어려운 내용은 아닌데 막상 프로그램을 작성하면 어렵죠 ㅎㅎ

    passport.use('signup', new LocalStrategy({
        usernameField : 'email',
        passwordField : 'password',
        passReqToCallback : true 
    },
    function(req, email, password, done) {
        User.findOne({ 'email' : email }, function(err, user) {
            if (err) return done(err);
            if (user) {
                return done(null, false, req.flash('signupMessage', '이메일이 존재합니다.'));
            } else {

                var newUser = new User();

                newUser.name = req.body.name;
                newUser.email = email;
                newUser.password = newUser.generateHash(password); 

                newUser.save(function(err) {
                    if (err)
                        throw err;
                    return done(null, newUser);
                });
            }
        });
    }));

usernameFieldpasswordField는 보안을 위한 파라미터로 default설정은 username과 password로 되어 있습니다. 바꾸고 싶으면 위와 같이 직접 써주면 됩니다.

passReqToCallback 파라미터는 req에 user의 데이터를 포함시킬지에 대한 여부를 결정하는 곳입니다. 만약에 이 설정이 fault가 되어 있으면 req.user로 정보를 불러올 수 없어서 로그인 확인 등의 프로그램을 작성하는데 불편함이 생깁니다. 따라서 예제와 같이 설정해주는 편이 좋습니다.

이어서 function에서는 사용자가 직접 작성한 정보를 바탕으로,

  • 기존에 등록된 이메일 인지?
  • 이메일이 새로운 이메일이라면 데이터를 할당하고
  • password는 암호화 시켜서
  • 전체 데이터를 데이터베이스에 저장

하는 로직으로 운영합니다.

 

로그인 하는 방법도 회원가입과 유사합니다. 다만 유저의 데이터를 확인해서 다르면 거부하고, 맞으면 넘겨주는 방식으로 하면 됩니다.

    passport.use('login', new LocalStrategy({
            usernameField : 'email',
            passwordField : 'password',
            passReqToCallback : true 
        },
        function(req, email, password, done) { 

            User.findOne({ 'email' : email }, function(err, user) {

                if (err)
                    return done(err);
                if (!user)
                    return done(null, false, req.flash('loginMessage', '사용자를 찾을 수 없습니다.'));
                if (!user.validPassword(password))
                    return done(null, false, req.flash('loginMessage', '비밀번호가 다릅니다.')); 
                return done(null, user);
            });
        }));

회원가입과 다른 부분은 데이터베이스에서 확인하는 부분입니다.

req.flash는 passport에서 지원하는 connect-flash라는 플래시메세지 모듈입니다. 반드시 저 모듈을 사용할 필요는 없고 프로그래머에 따라서 다양하게 구현될 수 있습니다. 다만 이 모듈이 편한 이유는 전역변수로 지정이 되어 있어서 어느곳에서든지 req.flash로 해당 메세지를 불러올 수 있다는 것입니다.

connect-flash에 대한 자세한 정보는 여기에서 살펴보시길 바랍니다.

 

‘/models/user.js’를 생성하고 mongoose를 이용해 scheme를 만들어 줍니다.

mongoose의 좋은 점 중의 하나가 scheme를 만들어서 자동으로 유효성을 체크해준다는 것인데요, 우리가 저장할 데이터는 사용자이름, 이메일, 암호입니다. 이것들을 scheme로 만들어서 적용을 해보도록 하겠습니다.

‘/models’라는 디렉토리를 생성하고 user.js라는 파일을 만들어줍니다. 이 곳에서 user에 관련된 데이터베이스를 설계할 예정입니다.

var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');

var userSchema = mongoose.Schema({
    name: String,
    email : String,
    password : String
});

//password를 암호화
userSchema.methods.generateHash = function(password) {
    return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

//password의 유효성 검증
userSchema.methods.validPassword = function(password) {
    return bcrypt.compareSync(password, this.local.password);
};

module.exports = mongoose.model('User', userSchema);

scheme를 설정하고, password를 암호화/복호화 하는 세팅도 해줍니다.

여기에서 사용된 scheme.methods에 대한 설명은 mongoose에 관한 글에서도 했었는데요, 간단하게 설명하자면 scheme에 function을 넣는거라고 생각하시면 됩니다. 따라서 함수를 불러올때 model.function()으로 간단하게 쓸 수 있습니다. 이에 대한 예제는 이미 회원가입과 로그인 할 때의 예제에 들어가 있으니 참고하시면 됩니다.

 

‘/routes/index.js’에서 회원가입이나 로그인의  post요청에 대한 응답을 작성합니다.

회원가입이나 로그인의 작성방식은 유사합니다. 따라서 여기에서는 post요청에 대한 간단한 프로그램을 작성해보도록 하겠습니다.

회원인지 아닌지 인증하는 절차는 passport에 전부 정의가 되어 있습니다. 그래서 우리는 그 방법에 맞게 세팅만 해주면 끝납니다. 참 간단하죠?

passport.authenticate()라는 함수를 사용하게 될텐데, 이곳에는 인증절차가 마련되어 있습니다. 이 인증하는 함수가 실행되면 ‘/config/passport.js’에서 정의했던 방법에 따라서 인증을 실행합니다.

var passport = require('passport');

router.post('/signup', passport.authenticate('signup', {
    successRedirect : '/profile', 
    failureRedirect : '/', //가입 실패시 redirect할 url주소
    failureFlash : true 
}))

router.post('/login', passport.authenticate('login', {
    successRedirect : '/profile', 
    failureRedirect : '/', //로그인 실패시 redirect할 url주소
    failureFlash : true 
}))

참 간단하죠? passport.authenticate()에 의해서 인증과정이 시작되고 인증의 여부에 따라서 성공하면 successRedirect로 이동하고, 아니면 failureRedirect로 이동하게 됩니다. failureFlash를 true로 지정하면 로그인이나 회원가입이 실패했을 때 해당 플래시메세지를 보낼 수 있습니다. connect-flash를 사용하지 않으시는 분들은 이 부분은 빼도 됩니다.

 

로그인이 되었는지 확인하는 함수를 만들어 봅시다.

유저의 프로필이나 개인정보를 확인하는 곳에 아무나 들여보내면 안되겠죠? 그래서 사용자가 로그인이 되었는지 확인하는 함수가 필요합니다. 세션에 사용자 정보가 있을테니 그 곳을 뒤져서 어떻게 하면 될 것 같죠? 그런데 이미 passport에서 다 만들어 놨습니다. 우리는 환경만 만들어주고 그 함수만 사용하면 됩니다.

핵심이 되는 함수는 req.isAuthenticated()입니다. req의 정보중 현재 로그인 되어있는 사용자를 확인해서 로그인 여부를 true와 false로 반환해줍니다. 직접 저 함수를 사용해도 상관없습니다. 하지만 저는 그냥 만들어볼게요.

function isLoggedIn(req, res, next) {

    if (req.isAuthenticated()){
        return next();
    } else {
        res.redirect('/login');
    }
}

만약에 로그인이 필요한 곳이 있다면 이 함수를 사용하면 됩니다. 로그인이 되어있으면 확인 후 다음 절차로 진행하게 하고, 로그인이 되어있지 않다면 ‘/login’으로 보내서 로그인을 하게 합니다.

이 함수를 어디에 활용할까요? 유저가 프로필을 확인하는데 로그인이 되었는지 확인하는데 사용하면 좋을 같네요.

router.get('/profile', isLoggedIn, function(req, res, next) {
    res.render('index', { title: 'You are logged in.' });
});

프로필을 확인하려면 이렇게 로그인 여부를 확인하고, 로그인이 되었으면 로그인 되었다는 메세지를 보여주고, 아니면 로그인 화면으로 돌려주게 됩니다.

이렇게 활용하니까 보기도 편해지죠?

 

예제 프로그램을 그대로 써서 확인해보겠습니다.

위와 같이 간단하게 회원가입창을 만들어 줬고, 간단하게 정보를 입력했습니다.

 

제가 설계한대로 회원가입이 완료된 후에 profile로 url이 바뀌는군요! 그리고 문구가 바뀌면서 로그인 되었다는것을 직접 확인할 수 있게 했습니다.

 

그렇다면 데이터베이스를 확인해볼까요?

아까 등록한 이메일과 이름이 제대로 등록 되었군요. 하지만 password만은 암호화 되어서 알아볼수가 없네요.

회원가입과 로그인, 그리고 데이터베이스에 제대로 된 값이 들어가는지 확인해봤습니다.

 

이것으로 글을 마치겠습니다.

궁금하신 부분이나 이해가 안되는 부분은 댓글이나 질문을 올려주시면 답변해 드리도록 하겠습니다.

 

내용추가)


index.ejs에서 SIGNUP 부분은 Login과 똑같이 하면 적용됩니다. 다만 action만 ‘/signup’으로 바꿔주면 됩니다 ㅎㅎ

<h1>SIGNUP</h1>
<form action="/signup" method="post">
  <div>
    <label>Username:</label>
    <input type="text" name="name"/>
  </div>
  <div>
    <label>email:</label>
    <input type="text" name="email"/>
  </div>
  <div>
    <label>Password:</label>
    <input type="password" name="password"/>
  </div>
  <div>
    <input type="submit" value="Signup"/>
  </div>
</form>

이 부분만 추가하시면 회원가입되는 것을 확인 할 수 있습니다~

 

로그인 기능을 구현하신 분은 email을 통해 계정을 인증하는 방법도 시도해보세요~!

 

솜틀공장

이해가 안되시나요? 그럼 질문해주세요. 도움이 되셨나요? 그럼 응원글 하나 남겨주세요 ^^

62
Leave a Reply

avatar
18 Comment threads
44 Thread replies
2 Followers
 
Most reacted comment
Hottest comment thread
17 Comment authors
박성엽솜틀공장iiichoi이모저모 Recent comment authors
newest oldest most voted
Son빈
Member

안녕하세요 솜틀공장님~ 예제 잘 봤습니다^^

로그인 폼을 입력하는 index.ejs파일에서, sign up(회원등록) 폼 입력 코드가 예제에서 빠진 것 같아요.
email관련 input name이 없어서 그런지 예제대로 실행하면 view에러가 나네요~

아~ 혹시 관리자로 로그인 기능을 하려면 여기서 어떤 식으로 진행을 해야 하는지 궁금합니다.
항상 node.js 관련한 좋은 강의 감사드립니다~~~

jihee
Guest

안녕하세요!
저는 왜 똑같이 따라했는데 sign up이나 login을 누르면 not found 404가 나오는걸까유..

jihee
Guest

function isLoggedIn(req, res, next) {

if (req.isAuthenticated()){
return next();
} else {
res.redirect(‘/login’);
}
} 이부분은 index.js에 넣으면 되는건가요?

Coding
Guest
Coding

안녕하세요
passport.serializeUser is not a function
이라는 TypeError가 나는데 왜그런걸까요 ? ㅠㅠ

Son빈
Member

강의글 잘 봤습니다~
passport로 전달한 user데이터 값과 관련한 질문입니다.

가령,,
successRedirect : ‘/index’ 로 지정해주면,

“index.ejs”에서 이런식으로 user값을 전달해 줄 수 있죠?

그런데 “index.ejs” 외의 다른 ejs페이지에 user값을 전달해줄 수 있는 방법은 없나요;?
ajax나 jsonRPC로 index의 user정보를 전달하려고 하니 이게 제대로 된 방법인지 모르겠네요ㅎㅎ;;

input 태그의 value값에 user._id 정보를 담아서, 페이지 이동을 할 때 전달하는 꼼수도 생각하면서,, 혹시 더 좋은 방법이 있지 않을까 싶어서 질문남깁니다~

NodeEx_Newbie
Guest
NodeEx_Newbie

안녕하세요. 솜틀공장님. 포스트하신 내용을 가지고 샘플파일을 만들어보고 있는데요. URL 404 관련해서 문의드릴것이 있어 글을 남깁니다. 현재 제가 소스를 돌려보면 signup 부분은 정상적으로 작동하면서 /profile 로 redirect 가 되는데, login 부분은 HTTP 404 에러가 발생을 하더군요. log 를 확인을 해보니..

signup 부분은 POST /signup 302 후 GET /profile 304 로 redirect 가 정상적으로 작동하는거 같은데, login 부분은 POST /login 302 후 GET /login 404 로 login URL 을 다시한번 호출 하는것 같습니다. 어떤부분이 잘못되거나 결여된 걸까요??

Tommy
Guest
Tommy

얼마전부터 구글 Passport로그인 구현후에 웹뷰에서 부르면 정책적인 차단 문제가 발생하는데요.
이부분은 엄격히 모바일 웹에서만 사용해야 하는건지 아니면 다른 우회할 방법이 있는것인지요
고견 여쭙습니다~

Lim
Guest
Lim

참 쉽게 잘 설명하셨네요 ㅎㅎ

Lim
Guest
Lim

참쉽게 잘했어요.

Help
Guest
Help

안녕하십니까! 듀토리얼 잘 올려주셔서 너무 감사드립니다.
자바스크립트 자체를 처음 접해보면서 웹 구현도 처음해보는 입장이라 여러 부분 막힐때가 많이 있습니다.
혹시 config 폴더를 만들어서 passport.js 파일을 생성한 후
var User = require(‘../models/user’); 위 부분을 추가하라고 하셨는데, node www로 실행해보면 위 모듈을 찾을 수 없다는 에러 문구가 뜨면서 실행이 안되는 군요… 위 부분 해결할 수 있는 방법이 있을까요..?

오늘도너를
Member

안녕하세요~ 따라하다가 네임도 안겹치게 하고 싶은 코드를 짰는데 paasport.js부분에서 passport.use(‘signup’, new LocalStrategy({ usernameField: ’email’, passwordField: ‘password’, nicknameField: ‘name’, passReqToCallback: true }, function (req, email, password, name, done) { User.findOne({ ’email’: email }, function (err, user) { if (err) return done(err); if (user) { return done(null, false, req.flash(‘signupMessage’, ‘이메일이 존재합니다.’)); } else { User.findOne({ ‘name’: name }, function (err, user) { if (err) return done(err); if (user) { return done(null, false, req.flash(‘signupMessage’, ‘같은 닉네임이 존재합니다.’)); } else { var newUser = new User(); newUser.name = req.body.name; newUser.email = email; newUser.password = newUser.generateHash(password); newUser.save(function (err) { if (err) throw err; return done(null,… Read more »

bingary
Guest
bingary

안녕하세요~ 정말 쉽게 잘 정리해주셔서 감사합니다^^
웹통신은 초보라 하다가 이해안되는상황이 생겨서 질문드려요..
크롬이나 인터넷익스플로러같은 웹브라우저를 통해서 로그인을하면
serializeUser이후 리다이렉트로 profile 이동시 isLoggedIn의 req.isAuthenticated()에서 true가 떨어지는데, C#의 WWW 클래스를 통해서 접속하게 될때는 저기서 false가 나서 인증이 되지않네요..
혹시 관련해서 어떤 문제인지 알수있을까 해서 질문올려봅니다.

궁금..
Guest
궁금..

안녕하세요. 게시글 잘 봤습니다. ^^
이 passport local은 웹 브라우저에서 쿠키, 세션을 통한 인증으로 알고있는데요.
그래서 궁금한 점은
저는 웹 페이지를 통한 로그인이 아닌 모바일 앱에서 로그인하는 것을 node js 서버로 만들려고 합니다.
혹시 access token을 통한 다음과 같은 방식의 인증을 passport를 통해 할 수 있나요?
1. 로그인 api 요청
2. 서버에서는 access token 생성, 디비(?)에 저장, 응답으로 access token 전달
3. 클라이언트(모바일 앱)에서 다른 api 요청시 전달받은 access token 을 같이 전달
4. access token 보고 유효하면 응답 그렇지 않으면 잘못된 토큰 오류 전달

kimsunho
Member

안녕하세요. 솜틀공장님 쉬운 설명으로 예제를 잘 보았습니다. ㅎ 혹시 따로 예제 파일을 받거나 할 수 있는지요? 제가 따라서 하고 있는데 router.post(‘/login’, passport.authenticate(‘login’, { successRedirect : ‘/register’, failureRedirect : ‘/’, //로그인 실패시 redirect할 url주소 failureFlash : true })) 를 /routes/index.js 에 붙이자 에러가 뜨면서 router is not defined라고 떠요 ㅠㅠ 이 문제는 어떻게 해결하면 좋을까요? AWS를 이용하여 데이터베이스를 연결한 것인데 기존에 index.js에는 대부분 파일들이 exports.indexpost = function (req, res) { res.render(‘index’, { title: ‘Recomics’ }); }; 이런식으로 써있습니다 ㅎ 기존에 제가 passport를 쓰기전에는 exports.indexpost = function (req, res) { var err_msg = []; var username = req.body.userid; var password = req.body.userpass;… Read more »

jay
Guest
jay

완전 알찬 강의 잘봤습니다^^!
login 페이지에서 flash는 어떻게 띄울지 설명이 없는거 같네요..
변수값으로 flash에 값이 있으면 alert 시키면 되는걸까요?
또, 저는 몽고를 쓰지 않구, mysql을 사용합니다. 이런경우에 findOne나 findById의 함수는 없기때문에, 제가 임의로 무식하게 짜넣었는데요~ 혹시 mysql의 케이스에서 상기 예제 코드처럼 잘 짜여진 패키지를 알고 계신지 궁금합니닷!!

노터닝백
Member

안녕하세요. 강의 감사합니다.

궁금한 것이 있는데요.
로그인시 사용자 정보를 db에서 읽어 오는 것 까지는 되는데
userschema에 있는 validPassword 메소드 호출시 user object가 넘어가지 않아서인지
아래 에러가 발생합니다. (this.local.password) this를 프린트 해보면 빈 객체만 넘어오네요.
TypeError: Cannot read property ‘password’ of undefined
혹시 뭔가 설정이 빠진게 있을까요?

이모저모
Guest
이모저모

저도 같은 에러가 나서 이것 저것 찾다 보니 local 를 제거하고 this.password 로 하니 되네요

choi
Guest
choi

안녕하세요~ node js 에대해 공부중입니다. 이 예제를 따라하고 오류뜨는것은 다 해결했습니다. 그런데 회원가입을 하면 success redirection 에 의해 /profile로 넘어가게되는것같은데요. 여기서 failredirection url로 넘어가게되네요 ..

iii
Guest
iii

mongo DB connected…
true
serial { _id: 5a62b396d44d1d10179a2b2f,
name: ‘a’,
email: ‘b’,
password: ‘$2a$08$P13nA7ZYuuuVvlcYWghbJu29k1SGAu5MpG8vEErNie/BZysSemggO’,
__v: 0 }
POST /login 302 232.646 ms – 60
false
GET /profile 302 17.283 ms – 56
GET /login 200 28.542 ms – 871
GET /stylesheets/style.css 304 12.445 ms –

현재 서버로그 데이터입니다.
serializeUser시에 값을 출력한겁니다.
그런데 밑에 보시면 false는
res.isAuthenticated()의 반환값입니다. 그래서 로그인이 되지않는현상이 일어나는데 어떻게 해야할까요?

iii
Guest
iii

해결되었습니다~

박성엽
Member

하아… 덧글쓸려고 회원가입했습니다. 일단 가지고 계신 지식을 이렇게 알려주셔서 무한히 감사드립니다.. 그런데… 소스중에 틀리신 부분이 너무 많네요… 전체 풀 소스를 올려주셔도 아래에 있는 분들이나 저같이 삽질하는 일은 없을텐데요… 수정 요청 드리는 부분입니다. 1. index.ejs 파일에서 login form 에 사용자명 필드가 username 으로 되어 있는데 passport.js 의 login 부분에 usernameField가 email 로 되어있어서 로그인이 안되는 부분이 있습니다. 2. passport.js 설정 부분에 “위의 코드를 app.js의 적당한 부분에 씁니다.” 이멘트가… 적당한 부분에 넣었더니 돌지 않습니다. 그리고 ” 이 설정을 붙일때 주의해야 할 점은, 기본적으로 node.js가 비동기 방식이지만 app.use는 동기식으로 동작합니다. 따라서 어디에 붙이느냐에 따라서 프로그램이 실행되지 않을 수 있습니다.” 이미 이 사태가 벌어질것을… Read more »