passport-facebook を使って Facebook の OAuth 認証を実装してみた

Web アプリに OAuth 認証をサーバーサイドで簡単に実装するために passport と Express を触ってみた雑記です。
以前、Node.js + Socket.io の勉強がてら Facebook 認証を通してチャットルームにアクセスするようなアプリを作ったので、それをもう少しスリム化するのをモチベーションに実装してみました。

ちなみに以前作ったアプリに関する記事は以下。

* [一番簡単なFacebookログイン(OAuth2)の実装方法](http://qiita.com/ynunokawa/items/4c9147d2743d36e63832)
* [FacebookメッセンジャーのConversation IDを利用してチャットルームUIを作る](http://qiita.com/ynunokawa/items/48ecf8c65c69bba72870)
* [Socket.ioを使ったチャットルーム ロジックの実装](http://qiita.com/ynunokawa/items/564757fe6dbe43d172f8)

さて今回使った代表的なパッケージと簡単な役割はこんな感じ。

* [passport-facebook](https://github.com/jaredhanson/passport-facebook) : OAuth 認証
* [express](https://github.com/strongloop/express) : Web アプリ構成 & Web サーバー
* [ejs](https://github.com/tj/ejs) 認証前後で View を動的に切り替え

passport-facebook さえインストールすれば、express や ejs などの依存パッケージはくっついてきます。認証フローなんかもほとんど設定レベルで作れちゃいます。

## OAuth 認証の実装
passport-facebook の [example](https://github.com/jaredhanson/passport-facebook/tree/master/examples/login) が Express の最小構成な感じで使いやすそうだったので、これをベースに作りました。

__フォルダー構成__
exapmles/login
　|---public (静的ファイル置き場)
　|---views (els 置き場)
　|---app.js ←ここが本記事のメイン
　|---package.json

以下、認証系をやってくれるスクリプトで書き換えた箇所を挙げていきます。
実装は Heroku にデプロイする前提でやってます。

__アプリ ID とシークレット__

```javascript:app.js
var FACEBOOK_APP_ID = "--insert-facebook-app-id-here--"
var FACEBOOK_APP_SECRET = "--insert-facebook-app-secret-here--";
```

[facebook for developers](https://developers.facebook.com) でアプリを登録して ID とシークレットを発行して、ここにコピペでもいいですし、環境変数としてコマンドで入力もありです。
今回はコード上に晒したくないので、環境変数を使います。

```javascript:app.js
var FACEBOOK_APP_ID = process.env.FACEBOOK_APP_ID;
var FACEBOOK_APP_SECRET = process.env.FACEBOOK_APP_SECRET;
```

__コールバック URL__

```javascript:app.js
passport.use(new FacebookStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET,
    callbackURL: "http://localhost:3000/auth/facebook/callback"
  },
  function(accessToken, refreshToken, profile, done) {
    process.nextTick(function () {
      return done(null, profile);
    });
  }
));
```

passport に認証に必要な情報を放り込むところで、コールバック URL を定義します。
コールバック URL も Facebook for developers 上で設定します。
ローカルの開発環境であれば、`http://localhost:3000` で OK。本番を見据えれば相対パスでもいいと思います。
ただ、ここも先と同様に環境変数にしちゃいます。
`OR` で開発環境もいけるようにしとくと便利だと思います。

```javascript:app.js
passport.use(new FacebookStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET,
    callbackURL: process.env.CALLBACK_URL || "http://localhost:3000/auth/facebook/callback"
  },
  function(accessToken, refreshToken, profile, done) {
    process.nextTick(function () {
      return done(null, profile);
    });
  }
));
```

__ポート__

```javascript:app.js
app.listen(3000);
```

ポートは 3000 決め打ちになってるので、これも環境変数で。
なお、socket.io を使いたいので、express ではなく、http モジュール使って createServer でポートを指定しています。

```javascript:app.js
var server = require('http').createServer(app);
var port = process.env.PORT || 3000;

server.listen(port);
```

## 起動してみる (ローカル)

いろいろ環境変数使ってるので、こんなコマンドで実行。

```
$ FACEBOOK_APP_ID=*** FACEBOOK_APP_SECRET=*** node app.js
```

実行後は `http://localhost:3000` でブラウザー起動して確認できます。

## 起動してみる (Heroku)

デプロイは GitHub 経由で。いろいろ晒したくないものは環境変数化してるので、GitHub でも怖くないです。
Heroku にログインして作っておいたアプリに環境変数を設定します。

```
$ heroku login
$ heroku config:set FACEBOOK_APP_ID=***
$ heroku config:set FACEBOOK_APP_SECRET=***
$ heroku config:set process.env.CALLBACK_URL=***
```

あとは Heroku にデプロイして、起動したら動きます。かんたーん！

![map-chatter.gif](https://qiita-image-store.s3.amazonaws.com/0/81547/866e8f0c-44e3-b6bb-9290-954a1342532f.gif)

できあがったものは GitHub に置いてあるので気軽に Fork なりクローンなりして使ってください。⭐︎貰えると喜びます。

* [__map-chatter | GitHub__](https://github.com/muxlab/map-chatter)