인증¶
passport.js¶
패스포트는 노드의 인증을 위한 미들웨어입니다. strategy
를 설정한 후 authenticate()
메소드를 이용해서 사용합니다.
설치는
npm install --save passport
인증¶
인증은 passport.authenticate(‘strategy’) 메소드를 호출하면 됩니다. authenticate() 메소드를 사용할 때 인자로 strategy를 지정해야 합니다.
app.post('/login',
passport.authenticate('local'),
function(req, res) {
// If this function gets called, authentication was successful.
// `req.user` contains the authenticated user.
res.redirect('/users/' + req.user.username);
});
기본적으로 인증이 실패하면 401 Unauthorized 상태를 반환하고 다음에 있는 미들웨어들을 더이상 실행하지 않습니다. 인증에 성공하면 req.user에 인증된 사용자를 설정하고 다음 미들웨어들을 실행합니다. [1]
리다이렉트¶
인증 과정이 끝난 후 어디로 보낼 것인지를 결정합니다.
app.post('/login',
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login' }));
위의 코드는 인증이 성공하면 홈페이지로 가고 실패하면 로그인 페이지로 이동합니다.
플래시 메시지¶
리다이렉트와 동시에 상태 정보를 표시하기 위해 플래시 메시지를 이용합니다.
app.post('/login',
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login',
failureFlash: true })
);
failureFlash를 true로 설정하면 strategy의 verify 콜백에서 주어진 메시지를 에러 메시지와 함께 표시합니다.
또는 명시적으로 표시를 할 수 있습니다.
passport.authenticate('local', { failureFlash: 'Invalid username or password.' });
successFlash 옵션을 이용하면 성공시 메시지를 표시할 수 있습니다.
passport.authenticate('local', { successFlash: 'Welcome!' });
Note
플래시 메시지는 익스프레스(Express) 2.x에서는 req.flash()
함수를 이용하고 익스프레스 3.x는 connect-flash 미들웨어를 이용합니다.
세션 기능¶
기본적으로 패스포트는 인증이 한번 되면 계속적으로 상태를 유지합니다. 인증 유지를 원하지 않으면 session 옵션을 false로 설정합니다.
app.get('/api/users/me',
passport.authenticate('basic', { session: false }),
function(req, res) {
res.json({ id: req.user.id, username: req.user.username });
});
사용자 지정 콜백¶
내장된 옵션들로 원하는 인증을 할 수 없다면 사용자 지정 콜백을 이용할 수 있습니다.
app.get('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});
설정¶
strategy¶
use 함수를 이용합니다.
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ username: username }, function (err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
콜백 확인¶
strategy는 콜백 확인(verify callback)이라는 중요한 과정을 거칩니다. 콜백 확인은 사용자가 유효한 자격증명(credentials)들을 가지고 있는지를 확인하는 것입니다. 앞의 예에서는 username과 password가 자격증명들이 됩니다. 자격증명들이 유효하면 콜백확인은 done이라는 함수를 이용하여 유효한 사용자를 반환합니다.
return done(null, user);
만일 유효하지 않으면(암호가 다르면) done은 false를 반환합니다.
return done(null, false);
뿐만아니라 에러 플레시 메시지를 함께 표시할 수 있습니다.
return done(null, false, { message: 'Incorrect password.' });
예외가 발생하면 에러를 반환해야합니다.
return done(err);
인증 전략(Strategy)¶
Username & Password¶
가장 많이 사용되는 인증 방법은 사용자 아이디와 암호를 이용하는 것입니다. 이러한 절차는 passport-local이라는 모듈을 이용해 구현할 수 있습니다.
설치¶
$ npm install passport-local
네비게이션 [3]¶
네비게이션을 이용해서 인증하는 흐름을 살펴봅니다. 네비게이션은 리액트네비게이션을 사용합니다.
인증 화면¶
import React from 'react';
import {
ActivityIndicator,
AsyncStorage,
StatusBar,
StyleSheet,
View,
} from 'react-native';
class AuthLoadingScreen extends React.Component {
constructor(props) {
super(props);
this._bootstrapAsync();
}
// Fetch the token from storage then navigate to our appropriate place
_bootstrapAsync = async () => {
const userToken = await AsyncStorage.getItem('userToken');
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
this.props.navigation.navigate(userToken ? 'App' : 'Auth');
};
// Render any loading content that you like here
render() {
return (
<View style={styles.container}>
<ActivityIndicator />
<StatusBar barStyle="default" />
</View>
);
}
}
참조 사이트
[1] | 패스포트 문서: http://www.passportjs.org/docs/ |
[2] | 패스포트를 이용한 인증 https://medium.freecodecamp.org/learn-how-to-handle-authentication-with-node-using-passport-js-4a56ed18e81e |
[3] | 리액트네비게이션 인증 흐름 https://reactnavigation.org/docs/en/auth-flow.html |