勉強したことのメモ

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

  関連記事

【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を ...