Google Authenticatorを使って二段階認証を実装してみた

最近流行り(?)のワンタイム

この記事を三行にまとめると

Google Authenticatorを使った二段階認証
ライブラリを読み込んでいることが前提での話
ただのワンタイムパスワードとしての使い方も
最近はログインをする時に二段階認証が必要なサービスも結構増えてきた気がします。そこで今日はPHPでGoogle Authenticatorを使った二段階認証の実装方法を見ていきたいと思います。

二段階認証方法はいくつかやり方があると思うのですが、使ってみたらGoogle Authenticatorはわりと簡単に実装できたので個人的にオススメです。

ほんじゃあ早速行ってみましょー。



スマホにアプリをインストールする

今回の二段階認証はスマホにGoogle Authenticatorのアプリをインストールすることが必須となるので、まずはこいつをスマホにインストールしてください。

iPhone(App Store)
Android(Google Play ストア)



ライブラリを持ってくる

たぶん一からコード書いても実装は可能だと思うのですが、すでに先人がGoogle Authenticatorを手軽に使えるためのライブラリを用意してくれているので、今回はそれを使わせてもらいましょう。

GitHubで公開されているGoogleAuthenticatorのページからGoogleAuthenticator.phpのファイルを持って来て自分とのサーバーにアップすればOKです。

こっから先の話はこのライブラリを読み込んでいることが前提での話になります。



QRコードを作成する

ライブラリを持ってきたら最初にスマホで読み取るためのQRコードを作成します。

//ライブラリの読み込み
require_once 'GoogleAuthenticator.php';
$ga = new PHPGangsta_GoogleAuthenticator();

//秘密鍵作成
$secret = $ga->createSecret();

//QRコードのURLを取得
$url = $ga->getQRCodeGoogleUrl('名前', $secret, 'タイトル');
echo $url;

秘密鍵を作成し、その秘密鍵を使ってQRコード用のURLを取得しています。このURLにアクセスするとQRコードが表示されるので、インストールしたアプリでQRコードを読み取ればこんな感じにワンタイムなコードが表示されるようになります。

アプリの仕様だと思うけどこの画面スクショ禁止だった

タイトルと名前はURLの取得時に入力したものが表示されます。

それからここで作成した秘密鍵は認証の時にも必要になるのでデータベースに保存するなど何らかの形で保管しておく必要があります。



もしQRコードを管理画面などで表示させたい時はimgタグにURLを入れれば表示できます。

//ライブラリの読み込み
require_once 'GoogleAuthenticator.php';
$ga = new PHPGangsta_GoogleAuthenticator();

//秘密鍵作成
$secret = $ga->createSecret();

//QRコードのURLを取得
$url = $ga->getQRCodeGoogleUrl('名前', $secret, 'タイトル');
echo '<img src="'.$url.'" />;



いざ認証

続いて認証です。スマホに表示されているワンタイムのコードと先ほど作成した秘密鍵を使って認証します。

//ライブラリの読み込み
require_once 'GoogleAuthenticator.php';
$ga = new PHPGangsta_GoogleAuthenticator();

//認証
$check = $ga->verifyCode('秘密鍵', 'ワンタイムコード', 30);

if($check) {
  echo '認証成功';
}

ライブラリの「verifyCode」メソッドでtrueが返って来たら認証成功です。第一引数に先ほど作成した秘密鍵を入れて第二引数にスマホに表示されているコードを入力します。実際はフォームなどから送信すると思うので、POSTされた値を入れることになりますかね。

$check = $ga->verifyCode('秘密鍵', $_POST['code'], 30);

三番目の引数はコードが更新されてから何秒間有効にするかという設定です。スマホに表示されているコードは一分ごとに別の数字に書き変わりますが、変わった瞬間に前のコードが無効になるわけではなくて多少の猶予があります。この猶予を何秒間にするかというのが第三引数の数字です。ここでは30としているので、コードが新しくなっても30秒間は一つ前に表示されていたコードでも認証が通るようになります。

この数字はあまり長すぎない方が良いと思いますし、実際の運用では30秒も猶予を持たせる必要はない気もします。10秒とか15秒くらいでも十分じゃないかしら。






以上でGoogle Authenticatorでの認証は完了です。あとはこれをログインフォームに組み込めば二段階認証が実装できます。「IDとパスワードを入力 → 認証OK → コードの入力 → ログイン成功」という流れが一般的ですかね。

個人的には二段階じゃなくてただのワンタイムパスワードとしてIDと一緒に入力するという使い方もできるんじゃないかなと思っていますが、その辺は仕様次第ですかね。

二段階認証には他にSMS(ショートメール)でコードが送られてくるというやつもありますけど、あっちのやり方はSMSの送信の仕組みを実装するのがめんどいし何かとコストもかかってくると思うので、手っ取り早く実装したい場合はこのGoogle Authenticatorを使うのが良いんじゃないかなあと思います。
 もしかしたら何か関連しているかも? 
 みんなからのコメント 
まだコメントはいただけてないみたい……