カラクリスタ

Express.js + everyauthで認証する方法のメモ

概要: Express.js でユーザー認証したい時は everyauth が便利だよ!


こんにちま!

なんかものっそ久しぶりな気がしますが、皆さんこんにちま! いつも心に make money、悪い意味で年金が恋人、 にゃるらコト岡村 直樹(24)です。皆様お久しぶりです。

六月のはじめ、

  • いろいろあってうつ病になったりしたけどようやく復活してきました /post/50791597902

とかほざいてたんですが、あの後、特に梅雨が明けたぐらいから、 色々と有ってうつ病をぶり返してしまい、 いままでダウナーモードでネットするのもだるいわー、 iPad で Feed 消化とか Tumblr 閲覧とか 2ch watch とかもなにこれしんどい、 家事とかもうつらいんですけど状態! という状況をさまよっておりました。

ただ、最近はちょっと持ち直してきて、 薬飲み忘れて躁状態でプログラミングやってたり、 あるいはその次の日、超しんどい、何コレ……、とか そういう風な感じでしたが、一応日々なんとかやっております。

んで、最近はそんな感じだったんですが、本日のネタはこの間、 躁状態プログラミングやってた時に、

  • CoffeeScript + Express.js + everyauth

を使う際にモロハマりしたものの、無事解決出来てヤターとなったあたりのコトを、 つらつらっと書きたいと思います。

今回使用したライブラリの説明

  • Express.js node.js での Web Application framework

  • 最近 3.x 系が出た

  • 今回は 3.x 系を使用

  • everyauth node.js の connect.js 向け認証モジュール

  • 対応サイトが多い。代表格は Twitter、Facebook、Instagram、mixi とかも対応

  • express.js 3.x 系で使うには git branch から everyauth をインスコする必要あり

  • CoffeeScript JavaScript 書くのめんどいから使用

  • ちょさんにはでぃすられる

  • 個人的にはなれると結構らくちんです

Express.js + everyauthのハマりどころ

1. コードを書く順番

Express.jseverauthを一緒に使う場合、 everyauthの各種 API key 等の設定を書く順番が超重要になります。

どういうコトか、というと、everyauthでは認証モジュールの設定に関して、 coffeescript を使う場合では、

everyauth = require 'everyauth'
config    = require 'config'

everyauth.twitter.configure
consumerKey:    config.auth.twitter.consumer
consumerSecret: config.auth.twitter.secret
entryPath:      '/login/twitter'
redirectPath:   '/login/twitter/callback'
findOrCreateUser: ( session, token, secret, data ) ->
promise = @Promise()
promise.fulfill( id: "twitter:#{data.id}" )
return promise

という感じのコードを書く必要がありますが、 このコードが、

app.configure ->
# (略)

app.use express.cookieParser( config.cookie.secret )
app.use everyauth.middleware(app) # <- コレ

# (略)

を書くよりも だと、entryPathで指定した URL、 例えばlocalhost:3000/login/twitterにアクセスしても、 Cannot get /login/twitterな感じの 404 を拝み続けるはめになります。

なんで、everyauthで認証設定を書く時は、 express.jseveryauthの認証ミドルウェアを食わせる前に書きましょう。

2. everyauth.everymodule.findUserByIdfindOrCreateUserの組み合わせ方

この二つなんですが、似てるようで機能がちょっと違うので、 最初わけがわからないよ! な QB 状態でした。

で、今はわかったんで一応書くと、

  • everyauth.everymodule.findUserById データベースからユーザー情報を引っ張ってくる

  • ここで渡した Object が view helper の user オブジェクトに入る

  • findOrCreateUser ユーザー ID を見つけるか作る

  • ここで UserID をデータストアに保存しても良いけど、しなくても OK

重要なのは、User ID を所定の方法で返す事

という感じです。

具体的には、

everyauth.twitter.configure
(略)
findOrCreateUser: ( session, token, secret, data ) ->
promise = @Promise()
promise.fulfill({ id: "twitter:#{data.id}" }) # <- ココでUserIDを渡す
return promise

という感じのコードを書くんですが、 この時promise.fulfillに渡したオブジェクトの idプロパティの値が、everyauth.everymodule.findByIDの、

everyauth.everymodule.findUserById ( userId, callback ) ->
console.log(userId) # <- ココがさっきの`twitter:#{data.id}`になる
(略)

userIdの値になります。

この辺りのポイントというかハマりどころとしては、 こういう感じになるかと思います。

というわけで以上ハマりどころでした。

Express.jseverauthのハマり所としては、この二点ぐらいだと思うので、 この二点さえ押さえておけば、 後はオリジナルのドキュメント読めばなんとかなると思います。

ちなみに僕はこれを理解して、実際に動くコードを書き上げるまでに、 まるっと一日使ってしまいました。薬飲み忘れの躁状態って怖い。

まあ以上が、サンプルコードではわからなかったポイントかな、 と思います。


ちなみに本件とはあんまり関係ないですが、 6 月だったか 7 月だったかに、このブログ、 空繰再繰(カラクリサイクル)のルックスを変更していたりしました。

多分このブログを前にも見ていて、今回も見た人は気づいてるかなーとは思いますが、 一応告知まで。遅くなってすんまそん。

というわけで以上、久々の更新でした。まる。

#FIXME