JavaScriptでGoogleアカウントOpenID Connect認証

Node.js+Expressでタスク管理アプリを作りました。

githubbbpink/node-shpapad · GitHub

 

作った背景

  • もともとshpapadというタスク管理アプリを自作して使用していた
  • 2015年7月にGAEのMaster/Slave Datastoreがサービス終了し、アクセスできなくなってしまった(shpapadはこれを使っていた)
  • GAE特有のスピンアップ時間によるもっさり感がつらかった
  • 規模はデカくないしリソースが空いてるVPSRailsかExpressで速攻作りなおすか → 気分でNode.js+Express

実装の勘所(1) GoogleアカウントでOpenID Connect認証

まずGoogleデベロッパ登録をしたら、OpenID Connectをするためだけのプロジェクトを作成します。プロジェクト情報を参照して「OAuthクライアントID」と「クライアントシークレット」の2つを入手すれば実装前の準備は完了。(この記事を見ながらやった気がします)

認証の流れは、

  1. リダイレクト先URLをパラメタに積んだGoogleドメインへのリンクをユーザがポチッ
  2. 飛んだ先のGoogleドメイン内で、shpapadから要求されている権限をユーザが許可
  3. 1で通知したリダイレクト先URL(shpapadドメイン)にリダイレクトされる

です。

リダイレクト先URL

shpapadではログイン用のAタグが以下のように書かれています。

非常に長い...........

ここではGoogle公式ドキュメントを参考にして、5つのGETパラメタを設定しました。

  • client_id : 前述したOAuthクライアントID
  • response_type : "code"を指定します。(requiredなのになぜかcodeしか指定できない)
  • scope : ドキュメントを参照。shpapadではOpenID Connect認証をするだけなので"openid"だけを指定しています。
  • redirect_uri : 前述したshpapad側に帰ってくるためのリダイレクト先URL。
  • state : CSRF対策用の、shpapadサーバで発行したランダム文字列。

ユーザによる権限の承認

飛んだ先のGoogleドメイン内で、ユーザはアプリから要求されている権限が妥当であるか、そして承認するかどうかを判断します。

shpapadでは認証するだけなので"openid"のみを指定していますが、アプリケーションでメールアドレス等が必要な場合、リクエストパラメタのscopeに要求する権限を追加しておくと良いみたいです。

リダイレクトされたら

リダイレクト先URLにパラメタ付きでリクエストが飛んでくるので、サーバ側で受け取ります。

 

12行目まではリクエストパラメタに渡したstateの値の返却値チェックをしています。

shpapadではセッションに保存してあった値との照合をしています。

 

14行目からの流れは、

  1. リダイレクト先URLへのリクエストパラメタを取り出す
  2. 取り出したパラメタを使ってGoogleへトークンを要求
  3. 取得したトークンを使ってユーザ情報を取得

です。

 shpapadでは、内部のユーザIDを生成するための元データである、Googleのuser_idを取得しています。

ユーザ情報を取得する際、レスポンスボディが少し長い時があって、19行目からの「response.on("data" .....」を使って連結しておかないとしくじる場合がありました。

 

続く!

 

P.S. 見たまま編集だとソースコードかけないのね.....