##SailsとPassportでOAuth認可する
※追記:利用バージョンを書き忘れていたので追記
###バージョン
*Sails v0.9.9
*Passport.js v0.2.0
*passport-google-oauth v0.1.5
ここではGoogleのAPIを使ってOAuthしてみる。プロトコルのバージョンはOAuth2.0。Passportのストレテジはpassport-google-oauthでOAuth2Strategyを使う。
###コントローラ
/**
* AuthController
*
* @module :: Controller
* @description :: A set of functions called `actions`.
*
* Actions contain code telling Sails how to respond to a certain type of request.
* (i.e. do stuff, then send some JSON, show an HTML page, or redirect to another URL)
*
* You can configure the blueprint URLs which trigger these actions (`config/controllers.js`)
* and/or override them with custom routes (`config/routes.js`)
*
* NOTE: The code you write here supports both HTTP and Socket.io automatically.
*
* @docs :: http://sailsjs.org/#!documentation/controllers
*/
var passport = require('passport');
module.exports = {
login: function(req,res){
res.view();
},
authenticate: function(req,res){
passport.authenticate('google',{scope:['https://www.googleapis.com/auth/userinfo.profile']})(req,res);
},
authcallback: function(req,res){
passport.authenticate('google', {failureRedirect: 'login',successRedirect:'/message/success'})(req,res);
},
logout: function(req,res){
req.logout();
res.send('logout');
},
/**
* Overrides for the settings in `config/controllers.js`
* (specific to AuthController)
*/
_config: {}
};
loginからauthenticateを呼出し、Googleの認可フローにリダイレクト後、authcallbackにコールバックされて戻ってくる。
###api/services/passport.js
// api/services/passport.js
// This code is a little dirty. TODO: refactor this code for easy to read.
var passport = require('passport'),
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
passport.serializeUser(function (user, done) {
done(null, user.userId);
});
passport.deserializeUser(function (id, done) {
User.findOne({userId:id}).done(function(err, user){
if(err){
done(null,null);
} else {
done(null,user);
}
});
});
passport.use(new GoogleStrategy({
clientID:"",
clientSecret: "",
callbackURL: "http://localhost:1337/auth/authcallback"
},
function(accessToken,regreshToken,profile,done) {
process.nextTick(function(){
User.findOne({userId:profile.id}).done(function(err, user){
if(err){
return done(null,err);
} else {
if(!user){
User.create({userId:profile.id, userName:profile.name}).done(
function(err,createUser){
if(err){
return done(null,err);
} else {
return done(null,createUser);
}
});
} else {
return done(null,user);
}
}
});
});
}));
認可後の処理を含むフロー。セッションのデータのシリアライズとデシリアライズもここに記述。新しいユーザならユーザ情報をローカルのDBにも保存する。
###config/config_passport.js
// config/passport.js
// initialize passport as middleware
var passport = require('passport'),
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
module.exports = {
express: {
customMiddleware: function(app) {
app.use(passport.initialize());
app.use(passport.session());
}
}
};
midllewareとしてinitializeするための記述。Sailsのアプリ起動時に呼び出されて初期化される。
###views/auth/login.ejs
// views/auth/login.ejs
<h2>Google Login</h2>
<form action="/auth/authenticate" method="post">
<div><input type="submit"></div>
</form>
authenticateを呼び出しているだけ。
あとは必要に応じてpolicies.jsで認可前アクセスの制御(AuthControllerのメソッドは認可前でもアクセス可にしておく)とapi/policies内に配置するコードで認可前認可後のセッションのチェックのコードを追記する。