Slide 1

Slide 1 text

株式会社Nextat
 sawada
 Laravelで
 二要素認証を
    と実装してみた
 さくっ


Slide 2

Slide 2 text

自己紹介
 ● 株式会社Nextat
 ● 元銀行員
 ● 未経験エンジニア界隈(?)
 ● エンジニア歴2年ちょっと
 ● PHP(Laravel)の経験1年ちょっと
 ● 最近Nagoya Frontend User Groupの管理人になりました
 株式会社Nextat
 https://nextat.co.jp/ 
 
 Nagoya Frontend User Group 
 https://nfug.connpass.com/ 
 
 初登壇です!

Slide 3

Slide 3 text

目次
 1. 二要素(段階)認証とは?
 2. Google2FAとは?
 3. 実装環境
 4. アカウント登録の実装
 5. 認証の実装
 6. おまけ


Slide 4

Slide 4 text

目次
 1. 二要素(段階)認証とは?
 2. Google2FAとは?
 3. 実装環境
 4. アカウント登録の実装
 5. 認証の実装
 6. おまけ


Slide 5

Slide 5 text

知識
 ID/Password 秘密の質問 スマホ・タブレット 身分証明書 ICカード 指紋 顔 静脈 2つの要素を組み合わせる認証
 二要素認証とは?
 所有
 生体


Slide 6

Slide 6 text

知識
 ID/Password 秘密の質問 スマホ・タブレット 身分証明書 ICカード 指紋 顔 静脈 要素問わず2つの方法を組み合わせる認証
 二段階認証とは?
 所有
 生体


Slide 7

Slide 7 text

目次
 1. 二要素(段階)認証とは?
 2. Google2FAとは?
 3. 実装環境
 4. アカウント登録の実装
 5. 認証の実装
 6. おまけ


Slide 8

Slide 8 text

● 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
 シークレットキーとタイムスタンプを 用いて生成
 


Slide 9

Slide 9 text

Google2FAをアプリケーションに導入するにあたって
 大きく以下の2つの処理が必要になります
 Google認証システムへのア カウントの登録
 1
 ID・Password認証後
 OTPによる追加の認証
 2


Slide 10

Slide 10 text

目次
 1. 二要素(段階)認証とは?
 2. Google2FAとは?
 3. 実装環境
 4. アカウント登録の実装
 5. 認証の実装
 6. おまけ


Slide 11

Slide 11 text

環境・使用ライブラリ
 ● 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 


Slide 12

Slide 12 text

前提
 ● もともとID・Password認証を行っているアプリケーションを想定
 ● LaravelはWeb APIとして使用
 ● 認証はusersテーブル(Laravelが標準で用意)を使用
 ● usersテーブルに以下のカラムを追加
 ○ google2fa_secret
 ○ google2fa_timestamp 


Slide 13

Slide 13 text

目次
 1. 二要素(段階)認証とは?
 2. Google2FAとは?
 3. 実装環境
 4. アカウント登録の実装
 5. 認証の実装
 6. おまけ


Slide 14

Slide 14 text

Google2FAをアプリケーションに導入するにあたって
 大きく以下の2つの処理が必要になります
 Google認証システムへのア カウントの登録
 1
 ID・Password認証後
 OTPによる追加の認証
 2


Slide 15

Slide 15 text

ユーザー
 フロントエンド
 バックエンド
 ID・Password認証は成功している前提(ログイン中) 
 シークレットキーを
 リクエスト
 シークレットキーを
 発行し、QRコードにした ものと一緒に返す
 OTPとシークレットキー を元に認証
 QRコードを表示
 Google認証システムで 読み取り、アカウント登 録
 6桁のOTPを入力
 OTPとシークレットキー を送信
 シークレットキーをユー ザーに紐づけて
 保存


Slide 16

Slide 16 text

ユーザー
 フロントエンド
 バックエンド
 ID・Password認証は成功している前提(ログイン中) 
 シークレットキーを
 リクエスト
 シークレットキーを
 発行し、QRコードにした ものと一緒に返す
 OTPとシークレットキー を元に認証
 QRコードを表示
 Google認証システムで 読み取り、アカウント登 録
 6桁のOTPを入力
 OTPとシークレットキー を送信
 シークレットキーをユー ザーに紐づけて
 保存


Slide 17

Slide 17 text

シークレットキー発行
 use PragmaRX\Google2FA\Google2FA; $google2fa = new Google2FA(); return $google2fa->generateSecretKey();

Slide 18

Slide 18 text

QRコード化
 $g2faUrl = $google2fa->getQRCodeUrl( '組織名', 'アカウント名, $google2fa->generateSecretKey() );

Slide 19

Slide 19 text

ユーザー
 フロントエンド
 バックエンド
 ID・Password認証は成功している前提(ログイン中) 
 シークレットキーを
 リクエスト
 シークレットキーを
 発行し、QRコードにした ものと一緒に返す
 OTPとシークレットキー を元に認証
 QRコードを表示
 Google認証システムで 読み取り、アカウント登 録
 6桁のOTPを入力
 OTPとシークレットキー を送信
 シークレットキーをユー ザーに紐づけて
 保存


Slide 20

Slide 20 text

OTPとシークレットキーを元に認証
 $code = $request->input('code'); $secret = $request->input('secret'); $valid = $google2fa->verifyKey($secret, $code); // $validはboolになる

Slide 21

Slide 21 text

$validの扱い
 (ライブラリが例外を投げてくれると完全に思い込んでて小一時間詰まったやつ、いねえよなぁ!!?) 
 if (!$vaild) { throw new 認証コードが不適切Exception(); }

Slide 22

Slide 22 text

ユーザー
 フロントエンド
 バックエンド
 ID・Password認証は成功している前提(ログイン中) 
 シークレットキーを
 リクエスト
 シークレットキーを
 発行し、QRコードにした ものと一緒に返す
 OTPとシークレットキー を元に認証
 QRコードを表示
 Google認証システムで 読み取り、アカウント登 録
 6桁のOTPを入力
 OTPとシークレットキー を送信
 シークレットキーをユー ザーに紐づけて
 保存


Slide 23

Slide 23 text

シークレットキーをユーザーに紐づけて保存
 $user->update( [ 'google2fa_secret' => $secret ] );

Slide 24

Slide 24 text

目次
 1. 二要素(段階)認証とは?
 2. Google2FAとは?
 3. アカウント登録の実装
 4. 認証の実装
 5. おまけ


Slide 25

Slide 25 text

Google2FAをアプリケーションに導入するにあたって
 大きく以下の2つの処理が必要になります
 Google認証システムへのア カウントの登録
 1
 ID・Password認証後
 OTPによる追加の認証
 2


Slide 26

Slide 26 text

ID・Password認証
 開始
 2要素認証 の設定がON
 OTPによる認証
 アクセストークン発行 
 終了
 Yes
 No
 認証の実装フローチャート


Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

おまけ
 ★二要素認証ができなくなった場合のリカバリ方法を用意しよう
 - ex. Googleの8桁のバックアップコード
 
 ★二要素認証をしたブラウザを覚えさせよう
 - ブラウザのCookieに持たせる
 


Slide 29

Slide 29 text

サンプルレポジトリ
 https://github.com/sawadango/google2fa_example

Slide 30

Slide 30 text

おわり
 ご清聴ありがとうございました!