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が設定される。
参考サイト
関連記事
-
-
Google Maps APIで住所から経度緯度を取得する方法
やりたかった事はformに住所を入れてsubmitする際に、javascript ...
-
-
reCAPTCHA v2でAjaxは使わずにチェック状況を確認する方法
reCAPTCHA v2を実装する案件があり以前の記事を参考に組み込んでみたもの ...
-
-
formにGoogle reCAPTCHA v3を組み込み、PHPでスコア判定する方法
だいぶ前にGoogle reCAPTCHA v2をformに組み込むという記事を ...
-
-
Google Maps APIでメインカラーを変更する方法
GoogleMapAPIを用いたMAPでカラー変更をしたかった。カラーコードの指 ...
-
-
GASで祝日一覧(年月日と祝日名)データをJSON出力するAPIを作成
PHPのシステム案件で祝日を取得し、処理を行う箇所があった。Googleカレンダ ...
