勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

PHPとGoogle Authenticatorの組み合わせで2段階認証を実装する方法

  PHP Google

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が設定される。

 

参考サイト

https://blog.8bit.co.jp/?p=19630

 - PHP Google

  関連記事

formにGoogle reCAPTCHA v3を組み込み、PHPでスコア判定する方法
formにGoogle reCAPTCHA v3を組み込み、PHPでスコア判定する方法

だいぶ前にGoogle reCAPTCHA v2をformに組み込むという記事を ...

GASのプログラム実行時間計測方法と各種制限についてのメモ
GASのプログラム実行時間計測方法と各種制限についてのメモ

PHP等でプログラムを組んでいると、あまり実行時間について気にすることはなかった ...

GASとLINEを連携させて通知メッセージを送る方法のメモ
GASとLINEを連携させて通知メッセージを送る方法のメモ

Google Apps ScriptとLINEを連携させ、LINEに何らかの通知 ...

Googleのインデックスが消えて「Increase in ……」というメッセージが届いた際の対応方法
Googleのインデックスが消えて「Increase in ……」というメッセージが届いた際の対応方法

たまたま運営中のサイトをGoogleで検索したところ、いつもいる順位にいなかった ...

GASとGoogleアナリティクスを連携させ昨日分のアクセス数TOP3位のページタイトル及び合計アクセス数を取得する方法
GASとGoogleアナリティクスを連携させ昨日分のアクセス数TOP3位のページタイトル及び合計アクセス数を取得する方法

GASとGoogleアナリティクスを連携させて「昨日分のアクセス数TOP3位のペ ...