カラクリサイクル

『輝かしい青春』なんて無かった人の雑記

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

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


こんにちま!

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

六月のはじめ、

とかほざいてたんですが、あの後、特に梅雨が明けたぐらいから、 色々と有ってうつ病をぶり返してしまい、 いままでダウナーモードでネットするのもだるいわー、 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月だったかに、このブログ、 空繰再繰(カラクリサイクル)のルックスを変更していたりしました。

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

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