Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Laravelで二要素認証をサクッと実装してみた - PHPカンファレンス沖縄2022

sawada
August 26, 2022
1.3k

Laravelで二要素認証をサクッと実装してみた - PHPカンファレンス沖縄2022

sawada

August 26, 2022
Tweet

Transcript

  1. 自己紹介
 • 株式会社Nextat
 • 元銀行員
 • 未経験エンジニア界隈(?)
 • エンジニア歴2年ちょっと
 •

    PHP(Laravel)の経験1年ちょっと
 • 最近Nagoya Frontend User Groupの管理人になりました
 株式会社Nextat
 https://nextat.co.jp/ 
 
 Nagoya Frontend User Group 
 https://nfug.connpass.com/ 
 
 初登壇です!
  2. • Google認証システムを利用した2要素(段 階)認証です
 • 例の6桁の数字(One Time Password、以 降OTP)を入力するやつです
 • OTPはHOTPとTOTPの2つの生成方法が

    あります
 Google2FAとは?
 Google認証システム 
 (Google Authenticator) 
 HOTP
 
 H・・・Hash-based Message Authentication Code 
 シークレットキーとカウンターの値を 用いて生成
 TOTP
 
 T・・・Time-based
 シークレットキーとタイムスタンプを 用いて生成
 

  3. 環境・使用ライブラリ
 • Laravel Framework: 9.24.0
 • PHP: 8.1.8
 • antonioribeiro/google2fa:

    8.0.1
 • endroid/qr-code: 4.4.9
 
 
 レポジトリURL
 https://github.com/antonioribeiro/google2fa 
 https://github.com/endroid/qr-code 

  4. ユーザー
 フロントエンド
 バックエンド
 ID・Password認証は成功している前提(ログイン中) 
 シークレットキーを
 リクエスト
 シークレットキーを
 発行し、QRコードにした ものと一緒に返す


    OTPとシークレットキー を元に認証
 QRコードを表示
 Google認証システムで 読み取り、アカウント登 録
 6桁のOTPを入力
 OTPとシークレットキー を送信
 シークレットキーをユー ザーに紐づけて
 保存

  5. ユーザー
 フロントエンド
 バックエンド
 ID・Password認証は成功している前提(ログイン中) 
 シークレットキーを
 リクエスト
 シークレットキーを
 発行し、QRコードにした ものと一緒に返す


    OTPとシークレットキー を元に認証
 QRコードを表示
 Google認証システムで 読み取り、アカウント登 録
 6桁のOTPを入力
 OTPとシークレットキー を送信
 シークレットキーをユー ザーに紐づけて
 保存

  6. ユーザー
 フロントエンド
 バックエンド
 ID・Password認証は成功している前提(ログイン中) 
 シークレットキーを
 リクエスト
 シークレットキーを
 発行し、QRコードにした ものと一緒に返す


    OTPとシークレットキー を元に認証
 QRコードを表示
 Google認証システムで 読み取り、アカウント登 録
 6桁のOTPを入力
 OTPとシークレットキー を送信
 シークレットキーをユー ザーに紐づけて
 保存

  7. ユーザー
 フロントエンド
 バックエンド
 ID・Password認証は成功している前提(ログイン中) 
 シークレットキーを
 リクエスト
 シークレットキーを
 発行し、QRコードにした ものと一緒に返す


    OTPとシークレットキー を元に認証
 QRコードを表示
 Google認証システムで 読み取り、アカウント登 録
 6桁のOTPを入力
 OTPとシークレットキー を送信
 シークレットキーをユー ザーに紐づけて
 保存

  8. コードの流れ
 if (ID・Password認証が失敗した場合 ) { throw new UnauthenticatedException(); } if

    (ログインユーザーに2要素認証の設定がない場合 ) { return "アクセストークン発行 "; } if (OTPがリクエストにない場合 ) { throw new OTPを送ってねException(); } if (OTPが不適切な場合) { throw new UnauthenticatedException(); } return "アクセストークン発行 ";