sailsjs에서 passport를 이용한 사용자 인증이 가능케 하고자 한다.
passport의 strategy라는 각 인증 구현을 이용하면, 대개의 인증은 간단하게 이용할 수 있을거 같아서다.
참고자료
http://passportjs.org/guide/authorize/
http://www.bearfruit.org/2014/07/21/tutorial-easy-authentication-for-sails-js-apps/
https://github.com/kasperisager/sails-generate-auth
전제
passport binder에 해당하는 기능 구현은 직접 하지 않고, 상기 sails-generate-auth라는 구현체를 이용하고자 한다. 문서화가 아직 미약한 면이 있지만 소스가 그리 방대한것도 아니고 살짝 훑어보면 어떤 구조를 하고있는지는 간단하게 알 수 있다.
기본적으로 template을 통해 sails의 router, services, policy, controller, model등에 인증에 필요한 기능을 부분적으로 구현해 이용하는 형태를 취하고있다.
passport의 strategy는 config/passport.js에서 연결할 수 있으며, 기본적으로 local, google, twitter등의 인증은 기본으로 들어가 있는 상태이다.
기본적으로 auth에 필요한 파일들 및 디렉토리 구조를 작성해주는 형태이니 가급적이면 빈 프로젝트에서 진행하자.
git을 통해 확인해본 추가되는 파일들의 목록은 아래와 같다
api/controllers/AuthController.js
api/models/Passport.js
api/models/User.js
api/policies/passport.js
api/services/passport.js
api/services/protocols/
config/passport.js
node_modules/sails-generate-auth/
views/auth/
적어도 상기 파일들과 충돌이 일어나지 않게끔 준비가 되어있을 필요가 있다.
수순
sudo npm install sails-generate-auth passport bcryptjs validator
# on the sails project root...
sails generate auth
이후 각 파일별의 설정
필수사항
1. config/routes.json
'get /login': 'AuthController.login', 'get /logout': 'AuthController.logout', 'get /register': 'AuthController.register', 'post /auth/local': 'AuthController.callback', 'post /auth/local/:action': 'AuthController.callback', 'get /auth/:provider': 'AuthController.provider', 'get /auth/:provider/callback': 'AuthController.callback', 'get /auth/:provider/:action': 'AuthController.callback',
2. config/bootstrap.json
sails.services.passport.loadStrategies();
3. config/policies.json
'*': [ 'passport' ]
더불어 사용하고 싶은 인증형태의 관련 passport-strategy를 인스톨 할 필요가 있다.
sudo npm install passport-local
sudo npm install passport-twitter
sudo npm install passport-github
sudo npm install passport-facebook
sudo npm install passport-google-oauth
선택사항
1. 에러메세지를 지정하고 싶다면 아래와 같은 내용을 설정
{ "Error.Passport.Password.Invalid": "The provided password is invalid!", "Error.Passport.Password.Wrong": "Whoa, that password wasn't quite right!", "Error.Passport.Password.NotSet": "Oh no, you haven't set a password yet!", "Error.Passport.Username.NotFound": "Uhm, what's your name again?", "Error.Passport.User.Exists": "This username is already taken.", "Error.Passport.Email.NotFound": "That email doesn't seem right", "Error.Passport.Email.Missing": "You need to supply an email-address for verification", "Error.Passport.Email.Exists": "This email already exists. So try logging in.", "Error.Passport.Username.Missing": "You need to supply a username", "Error.Passport.Password.Missing": "Oh no, you haven't set a password yet!", "Error.Passport.Generic": "Snap. Something went wrong with authorization." }
2. 기본은 비인증도 접근할 수 있는 상태로 설정되어 있으나, 인증한정으로 하고싶다면 아래와 같은 내용을 config/policies에 설정
'*': ['passport', 'sessionAuth'], 'auth': { '*': ['passport'] }
특정 WaterlineORM(Database)을 통한 database-migration
sails lift를 실시할때 매번 database migration에 관해 물어오는데, scheme가 존재하는 database의 경우, 이 시점에서 alter를 선택하면 데이터베이스에 필요한 테이블들이 자동적으로 생성된다. (여기서 한 며칠 mysql에서 association이 아직 미지원인줄 알고 잘못된 테이블을 가지고 삽질을 했다(...))
sails-generate-auth는 내부적으로 2개의 모델간에 model-association기능을 이용하고 있다. 수동으로 이를 정의하게 되면 이 부분에서 문제가 발생할 수 있으니, 가급적 기동 초기에 alter선택지를 활용해서 데이터베이스에 테이블을 생성하도록 하자.
http://stackoverflow.com/questions/25255567/sails-js-production-env-sails-mysql-database-tables-not-created-upon-lift
Google oAuth2.0연계하기
1. ClientID & ClientSecret 발급
https://console.developers.google.com
상기 url에 접근한후, 인증용 프로젝트를 작성, 프로젝트 하위의 인증정보 페이지에서 ClientID를 작성한다.
2. ClientID & ClientSecret & Scope 설정
config/passport.js
google: {
name: 'Google',
protocol: 'oauth2',
strategy: require('passport-google-oauth').OAuth2Strategy,
options: {
clientID: '*****************',
clientSecret: '******************',
scope: 'https://www.googleapis.com/auth/plus.login',
scope: 'http://yourhost-url/auth/google/callback',
}}
개발자측에 문의해보니, scope에 ['email']이라 설정할 필요가 있다고 한다.
google: {
name: 'Google',
protocol: 'oauth2',
strategy: require('passport-google-oauth').OAuth2Strategy,
options: {
clientID: '*****************',
clientSecret: '******************',
scope: ['email'],
scope: 'http://yourhost-url/auth/google/callback',
}}
위와 같이 설정을 한 후에, 구글측에 접근하면 email만 요구하게 되고, 이를 통해 사용자 인증을 하게된다.
인증정보의 확인
sails-generate-auth는 조금 불친절하게도 로그인 상태를 확인할 수 있는 장소를 따로 설명해두지 않았다. 일단 인증상태정보를 확인하기 위해, 아래와 같은 route와 AuthController.js이하에 다음 코드들을 추가하고
http://your-host/whoami
로 접근해보자.
AuthController.js
whoami: function(req,res) { res.json(req.session);},
config/routes.js
'get /whoami': 'AuthController.whoami',
이후에 http://your-host/login 에서 로그인후 내용을 확인하면 다음과 같이 표시되는걸 알수가 있다.
logged-out
{
- cookie:
- expires: null,
- httpOnly: true,
- path: "/"
- passport: { },
- flash: { }
local-strategy
{
- cookie:
- expires: null,
- httpOnly: true,
- path: "/"
- passport:
- user: 2
- flash: { }
google-oauth-strategy
{
- cookie:
- originalMaxAge: null,
- expires: null,
- httpOnly: true,
- path: "/"
- passport:
- user: 1
- flash: { }
// If the profile object contains a username, add it to the user.if (profile.hasOwnProperty('username')) { user.username = profile.username;} else if(profile.hasOwnProperty('displayName')) { user.username = profile.displayName;
}
댓글 없음:
댓글 쓰기