Blog

[Draft]Authentication

January 21, 2014

[Draft]Authentication

* 작성중인 미완성의 글입니다.

개요

PassportMongoose를 적용해 Node.js 응용프로그램의 사용자 인증을 구현하는 방법을 정리합니다.

인증 전략(strategy)

Passport는 사용자 인증 요청을 처리하기 위해 전략(strategy)이라는 개념을 사용합니다. 인증 방법에 따라 적합한 전략을 사용할 수 있습니다.

로컬 전략

로컬 전략은 passport-local 패키지가 제공하는 사용자 이름과 암호를 이용한 전통적인 사용자 인증 전략입니다. 웹 사이트에 직접 사용자 계정을 만드는 경우에 사용됩니다.

암호 해시(hashed password)

계정 정보를 저장할 때 사용자가 입력한 암호의 직접적인 노출을 막기 위해 사용자가 설정한 암호 문자열을 그대로 저장하지 않고 비복원(단방향) 해시 값을 저장합니다. 이후 계정 인증과정에서 입력되는 암호 문자열을 동일한 알고리즘을 통해 해시 값을 얻은 후 두 값을 비교하는 방법으로 암호를 확인합니다. 해싱 알고리즘이 노출되더라도 해시 값만으로 암호를 유추할 수 없도록 salt를 사용합니다. 사용된 salt 값은 계정 정보에 함께 저장되어 사용자 인증 시 사용됩니다.

makeSalt: function() {
  return crypto.randomBytes(16).toString('base64');
},

encryptPassword: function(password) {
  if (!password || !this.salt) return '';
  var salt = new Buffer(this.salt, 'base64');
  return crypto.pbkdf2Sync(password, salt, 10000, 64).toString('base64');
}

Mongoose의 가상 특성(virtual attributes)을 이용해 password가 설정될 때 hashed_password 모델 속성 값을 대입하도록 합니다. password는 가상 특성이기 때문에 데이터베이스에 저장되지 않습니다.

UserSchema.virtual('password').set(function(password) {
    this._password = password;
    this.salt = this.makeSalt();
    this.hashed_password = this.encryptPassword(password);
}).get(function() {
    return this._password;
});

Sign up

데이터베이스에 사용자 엔터티를 만듭니다. provider 특성은 'local'로 설정합니다. 사용자 이름이 중복되거나 필수 필드가 누락되면 계정 생성에 실패합니다. 계정 생성이 성공하면 로그인합니다.

var user = new User(req.body);
var message = null;

user.provider = 'local';
user.save(function(err) {
  if (err) {
    switch (err.code) {
      case 11000:
      case 11001:
        message = 'Username already exists';
        break;
      default:
        message = 'Please fill all the required fields';
    }

    return res.render('users/signup', {
      message: message,
      user: user
    });
  }
  req.logIn(user, function(err) {
    if (err) return next(err);
    return res.redirect('/');
  });
});

Sign in

'local' 매개변수를 사용해 passport.authencitate() 함수를 호출 결과를 사용해 요청을 처리합니다.

app.post('/login', passport.authenticate('local', function (req, res) {
  res.redirect(...);
});

JWT(Json Web Token)

JWT

TwitterStrategy

FacebookStrategy

GitHubStrategy

GoogleStrategy

Array