#はじめに#
セキュリティ面での不安からポートフォリオの管理者ログインに2段階認証をつけようと思ってやってみたところ、結構詰まったので備忘録として残します。記事の内容がセキュリティ的に明らかにまずかったりした場合は、ご指摘頂けると幸いです。
#記事の対象者#
アプリにLaravelを使用していて、管理者アカウントにワンタイムパスワードによる2段階認証を検討している方。
#環境#
Laravel 8.76.2
Google2FA-Laravel v2.0.1 リンクはこちら
#参考#
https://github.com/antonioribeiro/google2fa-laravel
#Tinkerで管理者インスタンスを作成・鍵発行#
LaravelのコマンドラインツールであるTinkerを用いて、2段階認証を付与するインスタンスを作成します。インスタンス作成時に、Googleの認証アプリであるAuthenticatorに入力するための16桁の鍵を発行します。この鍵は後ほど認証アプリに入力するので、コマンドラインを閉じない or 控えておくかしておいてください。
>>> php artisan tinker
//使用するクラスを指定
>>> use Google2FA;
>>> use App\Models\Admin;
//認証アプリに入力するための鍵を発行
//**後で使用するので控えておく**
>>> $secret_key = Google2FA::generateSecretKey();
//管理者のインスタンスを作成
>>> $admin = new Admin();
//$adminの各種プロパティに値をセット
>>> $admin->hoge = hoge;
//先ほど作成した鍵をセット
>>> $admin->google2fa_secret = $secret_key;
//インスタンスの保存
>>> $admin->save();
//Tinkerの終了
>>> quit
#認証アプリに発行した鍵をセット#
認証アプリに先程発行した16桁の鍵をセットします。
#ログイン画面でワンタイムパスワードを入力#
ログイン処理時に正しいワンタイムパスワードか判定するためのinputを設置します。
//前後は省略します
<input type="number" name="one_time_password">
#ログイン処理#
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
$g2fa = app('pragmarx.google2fa');
$g2fa_key = Auth::guard('admin')->user()->google2fa_secret;
$one_time_password = $request->input('one_time_password');
if (!$g2fa->verifyGoogle2FA($g2fa_key, $one_time_password)) {
Auth::guard('admin')->logout();
return redirect()->route('admin.login')->with('alert', 'ワンタイムパスワードが間違っています。');
}
$message = "ログインが完了しました。";
return view('admin.dashboard', compact('message'));
}
通常認証を行った後、ログイン画面にて入力されたワンタイムパスワードが正しいワンタイムパスワードか判定し、誤っていた場合はログイン画面にリダイレクトするように設定しています。
#認証アプリで発行したワンタイムパスワードを入力#
認証アプリで発行したワンタイムパスワード以外の値を入力してもログイン画面にリダイレクトします。ログインしたい場合は、認証アプリで発行したワンタイムパスワードを入力してください。
#おわりに#
以上になります。セキュリティ的にまずかったり、コードにおかしな部分がありましたらご指摘いただけるとありがたいです。