勉強したことのメモ

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

  関連記事

Google Maps APIで現在地取得と目的地までのルートを表示させる方法

Google Maps APIを使って現在地を取得しつつ、目的地までのルートを表 ...

Google map APIでマーカー(アイコン)を好きな画像に変える

Googleマップでユーザーにマーカー画像をアップロードさせて、それをマップ表示 ...

reCAPTCHA v2でAjaxは使わずにチェック状況を確認する方法

reCAPTCHA v2を実装する案件があり以前の記事を参考に組み込んでみたもの ...

Google Maps APIで都道府県の中心地と県庁所在地にマーカーを立てる方法

Google Maps APIで都道府県の中心地もしくは県庁所在地にマーカーを立 ...

Google Maps APIでリアルタイムに現在地のマーカーを更新する方法

GoogleMapAPIを使って現在地を取得してその場所にマーカーを設置、その後 ...