Authenticatorアプリでログイン認証する!

Authenticatorは、二要素認証(2FA)を提供するアプリケーションで、アカウントのセキュリティを強化します。アプリは、TOTP(Time-based One-Time Password)プロトコルを使用して、時間に基づいた一回限りのパスコードを生成します。このコードは一定の時間ごとに変更されるため、セキュリティが高まります。
Google AuthenticatorやMicrosoft Authenticatorといったキーワードで検索するとアプリが見つかります。
動作サンプル
https://studio-key.com/Sample/Authn/GoogleAuthenticator/qrcode.php
AuthenticatorアプリをインストールしたらQRコードを読み込んで登録し、下部のリンクから認証フォームへ移動します。

あとはアプリに表示された数値を入力して認証するだけです。
インストールとプログラム
今回はGoogleAuthenticatorというライブラリを使います。
Github
https://github.com/sonata-project/GoogleAuthenticator
Install
composer require sonata-project/google-authenticator
qrcode.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?php require 'vendor/autoload.php' ; use Sonata\GoogleAuthenticator\GoogleAuthenticator; use Sonata\GoogleAuthenticator\GoogleQrUrl; $g = new GoogleAuthenticator(); $secret = $g ->generateSecret(); ?> <!DOCTYPE html> <html lang= "ja" > <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <title>QR code</title> </head> <body> <div style= "text-align:center; padding:30px" > <?php // QRコードURLを生成 $qrCodeUrl = GoogleQrUrl::generate( 'demo account' , $secret , 'STUDIOKEY DEMO' ); echo '<img src="' . $qrCodeUrl . '" alt="QR Code">' ; ?> <p><a href= 'form.php?secret=<?= $secret; ?>' >認証フォームへ移動</a></p> </div> </body> </html> |
form.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?php require 'vendor/autoload.php' ; use Sonata\GoogleAuthenticator\GoogleAuthenticator; use Sonata\GoogleAuthenticator\GoogleQrUrl; $g = new GoogleAuthenticator(); ?> <!DOCTYPE html> <html lang= "ja" > <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <title>GoogleAuthenticator Sample</title> </head> <body> <form action= "form.php" method= "get" s style= "text-align:center; padding:30px" > <input type= "hidden" name= "secret" value= "<?= @$_GET[" secret "]; ?>" > <p>Authenticatorに表示された数値を入力して下さい</p> <input type= "number" name= "number" > <button type= "submit" >SEND</button> <?php if ((isset( $_GET [ "number" ]) && $_GET [ "number" ]) && ( $_GET [ "secret" ] && $_GET [ "secret" ])){ if ( $g ->checkCode( $_GET [ "secret" ], $_GET [ "number" ])) { echo "<h2>認証成功</h2>" ; } else { echo "<h2>認証失敗</h2>" ; } } ?> </form> </body> </html> |
これだけです。
気をつけたいのはQRコード表示の際に生成されるシークレット($secret)が認証時に必要になる点です。実装の際はシークレットもデータベースに保存し、ユーザーと紐づけておく必要が有ります。
Microsoft Authenticatorについて
Microsoft Authenticatorでも同様の認証が可能ですが、他にも「番号一致」という少し異なる認証方法があります。他のAuthenticatorでは表示された番号をブラウザなどに入力するのに対し、Microsoft Authenticatorではブラウザに表示された数値をアプリに表示された数値の中から選択します。
類似の認証方法として、Salesforce Authenticatorも存在しますが、こちらはSalesforceに特化しています。上記の認証方法を含め、Microsoftが採用しているこれらの認証手法はMicrosoft関連のウェブサイトやアプリケーションでのみ利用可能であり、一般向けのライブラリ提供はされていないようです。
Authenticatorの導入に関して
スマートフォンへAuthenticatorアプリのインストールというハードルが有りますが、Authenticatorが端末依存のため、不正ログイン対策に威力を発揮します。ただし、スマートフォンを買い替えた場合などの移管に少し手間取る可能性が有ります。
既存システムへの導入は、通常通りログインした後にAuthenticator処理を行うことで、より高い対策になると思います。