PHPとGoogle Authenticatorの組み合わせで2段階認証を実装する方法
2段階認証と言えばSMS送信のケースが多く、その次に通常のメール送信というケースが多いように思う。ただ偶にGoogle Authenticatorというアプリを使うケース(My Nintendo Store等)があり、これを実装してみたいと思った。以下に実装方法をメモ。
目次
Google Authenticator
iOS版
https://apps.apple.com/jp/app/google-authenticator/id388497605
Android版
https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=ja
GoogleAuthenticator(ライブラリ)
GitHub
https://github.com/PHPGangsta/GoogleAuthenticator
インストール
手動でインストール
Composerでもいけるみたいだけどファイル1枚なので手動で問題なし。こちらのページからGoogleAuthenticatorTest.phpをダウンロードし、適当なディレクトリにアップロードする。
実装方法
シークレットキーの発行
ユーザ情報登録の際にシークレットキーをデータベースに登録しておく。シークレットキーは「Base32からランダムで16文字」でユーザ毎に発行しておくこと。
尚、以下ソースコードで発行できる。
$random = substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), 0, 16); echo $random; //HGDOQ5MR3LCPSZTJ
通常のログイン後に2段階認証を行う
ID&PASS等で通常のログイン後に2段階認証ページに進むような形になる筈。その2段階認証ページのソースコードが以下になる。
ソースコード
<?php require_once 'GoogleAuthenticator.php'; $auth_title = "Google Authenticatorのテスト"; //シークレットキーはユーザ個別のものを指定する $secret = "ABCDEFGHIJKLMNOP"; $ga = new PHPGangsta_GoogleAuthenticator(); //QRコードのURLを生成 $qrcode = $ga->getQRCodeGoogleUrl($auth_title, $secret); //2段階認証 $checkResult = false; $is_valid = false; $oneCode = ""; if( isset($_POST["oneCode"]) && isset($_POST["oneCode"]) != "" ){ $is_valid = true; $oneCode = $_POST["oneCode"]; $checkResult = $ga->verifyCode($secret, $oneCode, 1); } ?> <!doctype html> <html lang="ja"> <head> <title>2段階認証</title> </head> <body> <?php if($is_valid){ ?> <?php echo ( $checkResult ) ? '認証成功' : '認証失敗';?> <?php }else{ ?> <img src="<?php echo $qrcode; ?>"> <?php } ?> <form action="./" method="POST"> <input type="text" name="oneCode" value="<?php echo $oneCode; ?>" maxlength="6" minlength="6"> <button type="submit">認証</button> </form> <?php echo "シークレットキー: ".$secret."\n\n"; ?> </body> </html>
例のためシークレットキーを固定にしているが、実際は前述の通りユーザ毎のシークレットキーを指定すること。
ブラウザで表示
前述のソースコードをブラウザから開くと以下のように表示される筈。
上記のQRコードをGoogle Authenticatorのアプリから開くと6桁のワンタイムパスワードが生成され、そのパスワードをフォームに入力し「認証」ボタンをクリックすると認証が行われるのが確認できる筈。
時間のずれ
「$ga->verifyCode()」の第3引数で「30秒単位で許容される時間のずれ」を設定できる。8を設定した場合は前後4分ずれていても認証成功となる。尚、デフォルトは1が設定される。
参考サイト
関連記事
-
【2024年版】PHPMailerでGmailのSMTPサーバを経由してメールを送信する方法
だいぶ前に同じようなことをメモしたが、そちらの方法だと送信できずエラー内容を見た ...
-
Google Maps APIでメインカラーを変更する方法
GoogleMapAPIを用いたMAPでカラー変更をしたかった。カラーコードの指 ...
-
スマホでページ内リンクからGoogleMapアプリを開く
スマホでWebページにあるリンクをクリックした際にGoogleMapアプリを表示 ...
-
Google Maps APIで半径●メートル範囲を円で表示する方法
Google Maps APIでマーカーを立てて、そこから範囲●mもしくは●km ...
-
Google Maps APIとPHPを組み合わせて複数マーカーとウィンドウを連携させる方法
やりたかった事は以下の通り。 mysqlから経度緯度、マーカー名、マーカーIDを ...