九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、この間【Python】Pasori RC-S380で入退室システムをつくるという記事の中で、非接触型カードリーダーのPasori
をamazon
でポチってしまったことを書きました。
私はそれほど衝動買いする方ではないのですが、正直なところプログラムのために新しいガジェットを買って試してみるというのが予想以上に楽しい経験でした。
そして、今回の記事も同じようなものです。
業務で必要なものをamazon
で購入していたのですが、いろいろ見ているうちにある商品が売っていることに気がついてしまいました。
それが、この「Security Key by Yubico」です(3,600円😅)。
「一体これは何に使うの??」と思われたかもしれませんが、これは今後ログイン認証のメインになるだろうと言われている技術、「WebAuthn※」のためのセキュリティキーで、これがあれば超強力な認証システムが構築できるんですね。
※ Youtube動画を見る限り読み方は「うぇぶおーせん」と言っているようです。
ということで、今回は衝動買いプログラムの第二段として「WebAuthn」で2段階ログインを実装してみます。
開発環境: Laravel 5.8、Vue 2.6、Googhe Chrome 75、nginx + php-fpm
前提として
Laravelにphp artisan make:auth
で基本のログイン認証機能が使えるようになっていて、さらにテストユーザーが登録されていることが前提です。
もしまだ準備していない方は、以下ページの「ログイン、パスワードリマインダー機能を構築」を参考にして事前に作業をしておいてください。
また、WebAuthn
はローカルであってもHTTPS
接続が必須です。もしnginx
を使っているようでしたら以下を参考にしてみてください。
コピペでOK!ローカル環境にHTTPSを導入する(nginx編)
準備
実際に開発を始める前に必要になる準備をしておきましょう。
WebAuthn
に必要なパッケージをインストールするので、まずはそのパッケージに必要なPHPの拡張機能がインストールしておきましょう。
sudo apt install php7.2-gmp
インストールが完了したらウェブサーバーを再起動しておいてください。(httpd
の方はsudo systemctl restart httpd
)
sudo systemctl restart php7.2-fpm
そして、phpinfo()
で確認して以下のようになっていればうまくいっています。
では、WebAuthn
のパッケージを以下のコマンドでインストールします。
composer require asbiin/laravel-webauthn
パッケージをインストールしたら必要なファイルをパブリッシュ(コピー)しましょう。
php artisan laravelwebauthn:publish
すると、マイグレーションなどがLaravel
側にコピーされますので、以下のコマンドでDBにテーブルを作成しましょう。
php artisan migrate
※ もしforeign key
でエラーが出るようでしたら、連携するフィールドの型がちがっていることが原因ですので、database/migrations/2019_03_29_163611_add_webauthn.php
というファイルを開いて以下のように変更してみてください。
$table->unsignedInteger('user_id');
↓↓↓変更
$table->unsignedBigInteger('user_id');
Laravel側の作業
ではここからが、Laravel内での作業になります。
・・・と言っても実は先ほどインストールしたパッケージがほとんど全てのことをやってくれるので、ほんの少しだけで二段階認証を実装することができます。
ミドルウェアを登録する
まず、パッケージが用意してくれているミドルウェアをLaravelに登録します。
app/Http/Kernel.php
を開いて以下のように専用ミドルウェアを登録してください。
protected $routeMiddleware = [ // 省略 'webauthn' => \LaravelWebauthn\Http\Middleware\WebauthnMiddleware::class, ];
登録したミドルウェアをルートに適用する
あとは、先ほどのミドルウェアを2段階認証したいルートに適用するだけです。以下は/home
に適用させている例です。
Route::middleware(['auth', 'webauthn'])->group(function () { Route::get('/home', 'HomeController@index')->name('home'); });
テストしてみる
では実際にテストしてみましょう!
まずはセキュリティキーをパソコンのUSBに接続しておきます。
※ ちなみにGoogle Chrome
でしたらchrome://usb-internals/にアクセスし、device
タブをクリックした時に以下のように表示されていたらうまく認識されています。
では、https://example.test/login
にアクセスしてログインしてください。
そして、ログインが完了したらhttps://example.test/webauthn/register
にアクセスします。(このページでセキュリティキーを登録します)
すると上のようなポップアップが表示されてセキュリティキーが光ります(このキーだけの可能性あり)ので、指をタッチ。
もし登録がうまくいくと、リダイレクトします。
では、一旦ログアウトして再度ログインしてみましょう。
ここからが2段階認証になります。
この状態でログインボタンをクリックすると、再度以下のポップアップが表示されますので、同じく指をタッチしてログインしてください。
これで認証ができたら2段階認証は完成です。
お疲れ様でした!
ちなみに
今回利用したパッケージは日本語対応していませんが、以下のようにすることで英語表記を上書きすることができます。
まず、/resources/lang
フォルダ内にwebauthn
というフォルダをつくり、さらにその中にja
フォルダ、さらにその中にerrors.php
とmessages.php
というファイルを作成します。
また、翻訳内容はそれぞれ以下になります。
(error.php)
<?php return [ 'user_unauthenticated' => 'Webauthnで認証する前にログインする必要があります。', 'auth_data_not_found' => '認証データが見つかりません。', 'create_data_not_found' => '登録データが見つかりません。', 'object_not_found' => 'オブジェクトが見つかりません。', 'not_supported' => 'ブラウザがWebAuthに対応していません。', 'not_secured' => 'WebAuthnではセキュアな接続が必要になります。もしHTTP接続でテストする場合は「localhost」を使ってください。', 'key_already_used' => 'このキーはすでに登録されています。もう一度登録する必要はありません。', 'key_not_allowed' => '処理がタイムアウトしたか拒否されました。', ];
(messages.php)
<?php return [ 'buttonAdvise' => 'セキュリティキーにボタンがあるようでしたら、押してください。', 'noButtonAdvise' => 'もしないようでしたら、一度外してもう一度接続してください。', 'success' => 'キーが検出され、認証されました。', 'insertKey' => 'セキュリティキーを接続してください。', 'cancel' => 'キャンセル', 'auth' => [ 'title' => 'セキュリティキー認証', ], 'register' => [ 'title' => 'セキュリティキーを登録', ], ];
これらを設置すると以下のようになります。
おわりに
ということで今回はWebAuthn
をLaravel
で実装してみました。
実はですが、当初は認証からキーの登録まで全て自分でコードを書いていたのですが、正直なところ(おそらくセキュリティには必要なのだろうとは思うのですが)「なんでこんな仕様なの!?」みたいなデータ構造になっていたので、結果的に公開されているパッケージを使うことにしました。
まだ今のところ、それほどPHP
のWebAuthn
のパッケージは多いわけではないようですが、これからWebAuthn
が人気になってきたら、きっとLaravel
本家の方でも実装していくんじゃないかとも思いますので、これからも情報チェックをしていきたいと思います。
ぜひみなさんも強力な認証システムを構築してみてはいかがでしょうか。
ではでは〜!