[Draft]Authentication
* 작성중인 미완성의 글입니다.
개요
Passport에 Mongoose를 적용해 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