イントロ
ちょっとした思いつきで、pet projectとして小さなサービス作ってみるか!!というのを昨日の夜に思いついたのですが。
・・年末〜年始でやろう!と思って熱の引いてたネタの焼き直しで。ふと「これなら形にできそうだぞ!」というアイディアが浮かんだので。
で、テーブル設計とかばっと出しつつ、必要な画面を考え始めたところで「ユーザー登録/認証周りどうしようかな〜」っていう・・・
作るだけなら強制ログイン状態を生み出して、まず「動くように作る」をして、そっから考えよ〜!でも良いのだし。そうするつもりだったのですが。
うん、パスワードとかtokenとか預かるの嫌だ!
やるにせよ、何か今風のないのかな〜と。
GitHub/Twitter/Gmail辺りのOAuth連携をやるか、昔ながらのId/Passログインを作るか。ああ、tokenも預かりたくないし、かといって改竄できそうなのも嫌だし、パスワードも預かりたくねぇな〜ていうかソーシャルのアバター使いてぇな〜なんかな〜〜〜
ってことで、Firebase Authenticateを使ってみようと思いたち。
すごい雑なログインシステム(まで
びっくりするくらい簡単に動いてしまって、まだびっくりしてます。
- まず プロジェクトを作る https://console.firebase.google.com/
- Authentication -> sign-in method で(とりあえず) email/passを有効にする
- コンソールのPJ概要にあるスニペットとウェブサイトで Firebase Authentication を使ってみる | Firebase を参考にいじる
で、出来上がったのが下のようなもの。
すごく雑なFirebaseAuthenticateログインフォーム · GitHub
・・・これだけでちゃんと動くっていう。。 驚きがありませんか。
やりたいことを整理する
モチベーションは「ログイン・認証機構をこっちで作りたくないし、秘密情報をこっちのストレージにおいておきたくない」です。
こんな我儘を実現するシステムとは・・・
- エンドユーザーの操作によって、3rd partyのプロバイダに対して、「有効なアカウント」のお墨付きをもらってくる
- エンドユーザーから、こちらのサーバーに「安全で安心な認証済み情報」が送られてくる
- こちらのサーバー上にあるユーザーデータと紐付けて、ログイン処理を実行する
このあたり、なんとなくJWTとか使ってみたら行けるのかな〜どうかな〜って思ってるんですけどね。使ったことないので。試してみる。
- サードパーティの JWT ライブラリを使用して ID トークンを確認する
- How to add JWT Authentication to a CakePHP 3 REST API | Bravo Kernel
- ※最終的に持っていきたい先は、目下Cakeなので・・!
ココらへんを読み解けば良いかな?
fireabase的には firebase.auth().currentUser.getIdToken()
で「トークン」がとれる、と。
この値をhttps://jwt.io/ でデバッガに渡してみると、認証情報が入ってるっぽい。
このuidの値から、こちらのユーザーデータに対して同一性を手繰り寄せて行けばよいのかな?
やってることはコレっぽいな。
Firebase Auth のユーザ認証機能を自前のデータベースと連携する - Qiita
「Firebase Admin SDKを使うか、JWTライブラリを使うか」という、正にドキュメント上で言及されていた分岐があるだけ〜という感じがする。
どっちも内容は同じな気がしていて、「Firebase Admin SDKを利用するメリットはなにか」というと、ドキュメントに書かれているこの辺りか。
提供された ID トークンが正しい形式で、期限切れではなく、適切に署名されていれば(デコードされた情報を取得できます)
逆にJWTについての但し書きは
(利用するためには)ID トークンのヘッダー、ペイロード、署名を確認します。
となっている。
つまり、JWT実装した場合は自前で検証をしなければならないーと。
先に貼った「CakeでJWT認証やってみよう」の記事においては 10. Testing JWT Authentication
の部分に当たるかな?
ということで、やることとしては
- client側では、Firebase Authenticateを通ったあとに「トークン」をこっちのサーバーに投げる
- こっちのサーバーでは、投げられたトークンを検証する
- 検証に通ったらアプリケーション上でのユーザー同定・ログイン処理を行う
ができりゃ、いーかなぁ
実際に「外部プロバイダ」でログインやってみる with GitHub
大体の処理の流れは掴んだ?と思うので。あとは理屈で覚えるより動かしながら眺めてみる。
ってことで、GitHubログインをやってみたい
JavaScript を使用して GitHub で認証する | Firebase
- まずは
sign-in method
でGitHubを有効にして - callback urlを確認して
- GitHubの認証appを新規作成して https://github.com/settings/applications/new
- さっき確認したcallback urlを参考にしつつ必要な情報を埋めて
- 登録するとアプリケーション詳細ページに飛ぶのでClient ID/secretを確認して
- Firebase consoleに戻って、ID/secretを記入する
サービス側の設定はこれでOK。
ココらへんから「HTMLファイルを直開き」だと動かなくなってくる(http:// or https:// で始める必要がある)ので、必要に応じて firebase serve
コマンドなどを用いてローカルサーバーを利用する
先のドキュメントを参考にして、スクリプトを書いていく ・・・いちおうgistにも貼ってはいるけれど、これだけで動いちゃう・・・
const provider = new firebase.auth.GithubAuthProvider(); firebase.auth().signInWithPopup(provider).then((result) => { console.log(result.user) }).catch((error) => { alert(error.message) })
意味わからないですね簡単すぎて・・・・
ということで、あとはサーバーサイドの実装。
簡単なusersテーブル付きのログインできるcake appを書く
もう、べったり先のブログを参考にして。 プラグイン使ってJWT認証どのくらい簡単にできるかな?に挑みます。
あ、でもCRUDプラグインはいいや。
ココらへん使いつつ、Docker環境用意してcakephp/appのproject作って〜っていうのはいつもの通りなので省略。
1. cakephp-jwt-authプラグインの設置
このように
# composer require admad/cakephp-jwt-auth Using version ^2.3 for admad/cakephp-jwt-auth ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 2 installs, 0 updates, 0 removals - Installing firebase/php-jwt (v5.0.0): Downloading (100%) - Installing admad/cakephp-jwt-auth (2.3.2): Downloading (100%) Writing lock file Generating autoload files > Cake\Composer\Installer\PluginInstaller::postAutoloadDump /app # bin/cake plugin load ADmad/JwtAuth /app/src/Application.php modified
2. usersテーブルの設置
親切にMigrationファイルのサンプルとか用意してくれてるの。すげー
で、ちょっと内容を変えたいので(icon urlとか足してみたい)、参考にしつつ少しいじる
bin/cake bake migration CreateUsers
して- こんな感じの内容を(下記
bin/cake migrations migrate
する
<?php use Migrations\AbstractMigration; class CreateUsers extends AbstractMigration { /** * Change Method. * * More information on this method is available here: * http://docs.phinx.org/en/latest/migrations.html#the-change-method * @return void */ public function change() { $this->table('users') ->addColumn('name', 'string', [ 'default' => null, 'limit' => 64, 'null' => false ]) ->addColumn('avatar_url', 'string', [ 'default' => null, 'limit' => 256, 'null' => false ]) ->addColumn('created', 'timestamp', [ 'default' => 'CURRENT_TIMESTAMP', 'limit' => null, 'null' => false ]) ->addColumn('modified', 'datetime', [ 'default' => null, 'limit' => null, 'null' => true ]) ->create(); } }
3. users周りのコードをザクッと
bin/cake bake all Users
しておく。
いろいろなファイルが出来上がる。
この時点で、 /users/add
とかを見ると、画面ができているよね
4. サインイン用のAPIエンドポイント
ここからが本番!って感じ。
tokenを投げてユーザー登録をする先
が必要になるので。
/api/user/signup.json
とでもしよう。
routes.phpに下記を追記
<?php Router::scope('/', function (RouteBuilder $routes) { // 省略 $routes->prefix('api', function (RouteBuilder $routes) { $routes->setExtensions(['json']); $routes->post('/users/signup', ['controller' => 'Users', 'action' => 'add', 'prefix' => 'api']); });
src/Controller/Api
ディレクトリを新設し、以下のように UsersController
を作成
<?php namespace App\Controller\Api; use App\Controller\AppController; use Cake\Http\Exception\NotImplementedException; class UsersController extends AppController { public function add() { throw new NotImplementedException('これからね!'); } }
この時点で、一旦routes.phpから $routes->applyMiddleware('csrf');
をコメントアウトしておいて、こんな感じのcurlを打ってみる
curl -X "POST" "http://localhost:8101/api/users/signup.json" -H 'Content-Type: application/json; charset=utf-8'
これで status:ok
といったレスポンスが返ってくれば、routingはこれでOK!
5. Enabling JWT Authentication
とのことなのだけど・・・はて・・・
長くなってきそうなので、一旦ここまで!
次にやることは
- cakephp-jwt-auth の仕事や中身について理解する
- 「How to add JWT Authentication to a CakePHP 3 REST API」で説明されているシナリオについて理解する
- 実際にFirebase Authenticateを利用したGItHubログインを実装してみる
で!