Slide 1

Slide 1 text

Kaigi on Rails 2024 / ykpythemind OmniAuthから学ぶOAuth 2.0

Slide 2

Slide 2 text

ykpythemind (ゆきぽよ) STORES 株式会社 エンジニアリングマネージャ ・音楽制作 ・ホラー映像制作 ・苦手な食べ物が多いです

Slide 3

Slide 3 text

OmniAuthに隠されている 認証・認可のプロトコル 今日のテーマ

Slide 4

Slide 4 text

OmniAuth gemを使ったことはありますか? 4 https://github.com/omniauth/omniauth

Slide 5

Slide 5 text

今日のテーマ : OmniAuthに隠されている認証・認可のプロトコル 5 そもそも認証・認可とは? OmniAuthでかんたん実装 3分でわかるOAuth 2.0とOpenID Connect OmniAuthなしで実装してみよう おまけ: 明日から使える Tips (1) (2) (3) (4) (5)

Slide 6

Slide 6 text

OmniAuthのマジックがわかるようになります 6

Slide 7

Slide 7 text

START!

Slide 8

Slide 8 text

そもそも認証・認可とは? (1)

Slide 9

Slide 9 text

そもそも認証・認可とは? 9 認証:個人を識別すること。    「誰であるか」 認可:対象物に権限を与えること。    「権限があるか」

Slide 10

Slide 10 text

そもそも認証・認可とは? 10 16:35- MOROHASHI Kyosuke

Slide 11

Slide 11 text

そもそも認証・認可とは? 11 Railsの認証 : authenticate_by https://github.com/rails/rails/blob/e009430309111c58f5fe67acec07aa9339bab931/guides/source/action_controller_overview.md

Slide 12

Slide 12 text

そもそも認証・認可とは? 12 Railsの認証 : authenticate_by https://github.com/rails/rails/blob/8ac995453a2a2efd789810a90319e6bb6f0e2aea/activerecord/lib/active_record/secure_password.rb#L41

Slide 13

Slide 13 text

そもそも認証・認可とは? 13 Railsの認可 : ロールの例 adminロールだけ 認可されている

Slide 14

Slide 14 text

そもそも認証・認可とは? 14 Railsの認可 : gem ● CanCanCommunity/cancancan ● varvet/pundit ● palkan/action_policy …

Slide 15

Slide 15 text

󰥗「Googleでログインさせたい」 これだけじゃない、実世界によくある話

Slide 16

Slide 16 text

OmniAuthでかんたん実装 (2)

Slide 17

Slide 17 text

OmniAuthでかんたん実装 17 サンプル: https://github.com/ykpythemind/kaigi-on-rails-2024 01_omniauth_google_signin

Slide 18

Slide 18 text

OmniAuthでかんたん実装 18 https://www.youtube.com/watch?v=4TP1lchNE6w

Slide 19

Slide 19 text

OmniAuthでかんたん実装 19 ● GoogleOAuth2 ストラテジを使う宣言 ● クライアントIDとシークレットの設定 ● 使うScopeの宣言 Rackを理解し Railsアプリケー ション開発の足腰を鍛えよう 11:35〜 hogelog

Slide 20

Slide 20 text

OmniAuthでかんたん実装 20 / Googleログインを開始するボタ ンを表示するページ /auth/google_oauth2/callback 認証結果をGoogleから受け取る エンドポイント

Slide 21

Slide 21 text

OmniAuthでかんたん実装 21 OmniAuthによる実装の隠蔽 このエンドポイントは何を しているのか??? AuthHashとは何か??

Slide 22

Slide 22 text

OmniAuthに隠されている 認証・認可のプロトコル OmniAuthの抽象化が優秀。でも、今日のテーマをおさらい

Slide 23

Slide 23 text

3分でわかるOAuth 2.0と OpenID Connect (3)

Slide 24

Slide 24 text

3分でわかるOAuth, OpenID Connect 24 OAuth 2.0 Webアプリの認可のためのプロトコル OpenID Connect Webアプリの認証のためのプロトコル OAuth2.0 を拡張して作られている The OAuth 2.0 Authorization Framework https://openid-foundation-japan.github.io/rfc6749.ja.html OpenID Connect Core 1.0 https://openid-foundation-japan.github.io/openid-connect-core-1_0.ja.html

Slide 25

Slide 25 text

3分でわかるOAuth, OpenID Connect 25 つまり OpenID Connectを覚えておけばつぶしが効く 典型的なサードパーティログインの用途ではOpenID Connectを用いるほうが適している

Slide 26

Slide 26 text

3分でわかるOAuth, OpenID Connect 26 OpenIDによる認証フローの概要 サードパーティログインさせたいときにOmniAuthが裏側やっていること ※ 認可コードフロー クライアントからIDプロバイダに認証リクエストを送る 認証レスポンスが返ってきたらトークンリクエストを送る 返ってきたIDトークンを検証して認証。必要に応じてアクセストークンを使 用 (1) (2) (3)

Slide 27

Slide 27 text

3分でわかるOAuth, OpenID Connect 27 クライアントからIDプロバイダに認証リクエストを送る 認証レスポンスが返ってきたらトークンリクエストを送る 返ってきたIDトークンを検証して認証。必要に応じてアクセストークンを使用 (1) (2) (3) 認証されたことを証明 するトークン (OpenID) 認可されたリソース にアクセスするため のトークン (OAuth)

Slide 28

Slide 28 text

🤯 3分ではわからないですね...

Slide 29

Slide 29 text

OmniAuthなしで 実装してみよう (4)

Slide 30

Slide 30 text

OmniAuth Philosophy 30 https://github.com/omniauth/omniauth/wiki/Philosophy

Slide 31

Slide 31 text

GoogleOAuth2 ストラテジ 31 このエンドポイントは何を しているのか??? GoogleOAuth2ストラテジのRequest Phaseを開始 答え

Slide 32

Slide 32 text

GoogleOAuth2 ストラテジ -> OAuth2ストラテジ 32 https://github.com/zquestz/omniauth-google-oauth2/blob/11af0784aeb6a195d4e1857bdf0f696dc6f80e4b/lib/omniauth/strategies/google_oauth2.rb https://github.com/omniauth/omniauth-oauth2/blob/c830138e399b207ad3ce832ed4db51e67030cdcb/README.md

Slide 33

Slide 33 text

OAuth2ストラテジ の Request Phase を読む 33 ※1 OAuth2.0の文脈で言えば厳密には認可が開始する。 (1) クライアントからIDプロバイダに認証リクエストを送る にあたる部分 ● リダイレクトなので認証リクエストというイメージがしにくいが、ここから認証が開始 する ※1 ● callback_urlは、 http://localhost:4567/auth/google_oauth2/callback が OmniAuthによって自動で設定される https://github.com/omniauth/omniauth-oauth2/blob/c830138e399b207ad3ce832ed4db51e67030cdcb/lib/omniauth/strategies/oauth2.rb#L58

Slide 34

Slide 34 text

自前でRequest Phase相当の実装をする 34 02_request_phase

Slide 35

Slide 35 text

自前でRequest Phase相当の実装をする 35 ● client_id … IDプロバイダに登録したクライアントIDを与えている。 ● redirect_uri … OmniAuthの例で使ったものと同じ。IDプロバイダに登録したものと一致 する必要がある。 ● response_type … 認可コードフローを用いるので “code” を指定する。 ● scope … emailやprofileへのアクセスを認可させるかを指定する。 “openid” を指定するとIDトークンがもらえる(OpenID Connectの拡張) 02_request_phase

Slide 36

Slide 36 text

自前でRequest Phase相当の実装をする 36 Googleアカウントの 認可エンドポイントにむけてリダイレクトする。

Slide 37

Slide 37 text

OmniAuth Philosophy 37 https://github.com/omniauth/omniauth/wiki/Philosophy 次はCallback Phase を実装

Slide 38

Slide 38 text

OAuth2ストラテジ の Callback Phaseを読む 38 https://github.com/omniauth/omniauth-oauth2/blob/c830138e399b207ad3ce832ed4db51e67030cdcb/lib/omniauth/strategies/oauth2.rb#L84 (2) 認証レスポンスが返ってきたらトークンリクエストを送る にあたる部分 ● まずはエラーハンドリング ● build_access_token methodへ

Slide 39

Slide 39 text

OAuth2ストラテジ の Callback Phaseを読む 39 https://github.com/omniauth/omniauth-oauth2/blob/c830138e399b207ad3ce832ed4db51e67030cdcb/lib/omniauth/strategies/oauth2.rb#L124 (2) 認証レスポンスが返ってきたらトークンリクエストを送る にあたる部分 ● get_token() でトークンリクエストを送っている ※1 ● “code”というクエリパラメータが認可コード。これは一度限り有効な引換券。 認可コードと引き換えにアクセストークンとIDトークンを得る ※1 実装は OAuth2 gemに委譲 https://gitlab.com/oauth-xx/oauth2/-/blob/main/lib/oauth2/strategy/auth_code.rb#L30

Slide 40

Slide 40 text

自前でCallback Phase相当の実装をする 40 (2) 認証レスポンスが返ってきたらトークンリクエストを送る 03_callback_phase

Slide 41

Slide 41 text

自前でCallback Phase相当の実装をする 41 (2) 認証レスポンスが返ってきたらトークンリクエストを送る トークンエンドポイントに特定のパラメータをPOSTする ● code … クエリパラメータで渡された認可コード ● client_id … クライアントID ● client_secret … クライアントシークレット。クライアント認証のために必要。 (IDプロバイダが、認証済みのクライアントからのリクエストであることを判別する) https://developers.google.com/identity/openid-connect/openid-connect?hl=ja#exchangecode 03_callback_phase

Slide 42

Slide 42 text

自前でCallback Phase相当の実装をする 42 トークンリクエストの結果 返ってきたIDトークンを検証して認証。必要に応じてアクセストークンを使用 (3) 残りは…

Slide 43

Slide 43 text

OmniAuthのAuthHashの正体 43 AuthHashとは何か?? 認証の結果得たIDトークンやアクセストークンを 使いやすい形で保持してくれているクラス 答え https://github.com/omniauth/omniauth/blob/e23567ac860f4adfb425db226d68a03235078941/lib/omniauth/auth_hash.rb#L8

Slide 44

Slide 44 text

AuthHashのデータの元になるロジックを読む 44 https://github.com/omniauth/omniauth-oauth2/blob/c830138e399b207ad3ce832ed4db51e67030cdcb/lib/omniauth/strategies/oauth2.rb#L50 omniauth-oauth2 omniauth/strategies/oauth2.rb auth_hash.credentials.token という形で参照可能になる アクセストークン

Slide 45

Slide 45 text

AuthHashのデータの元になるロジックを読む 45 https://github.com/omniauth/omniauth_openid_connect/blob/f9779f098dbc870c4789c1ff928c5883733f5366/lib/omniauth/strategies/openid_connect.rb#L100 アクセストークンとほぼ同じ だが、verify_id_token!メソッドで id_tokenの妥当性を検証している IDトークン omniauth_openid_connect omniauth/strategies/openid_connect.rb

Slide 46

Slide 46 text

自前でアクセストークンとIDトークンを扱ってみよう 46 04_use_access_token_and_verify_id_token

Slide 47

Slide 47 text

自前でアクセストークンとIDトークンを扱ってみよう 47 IDトークンは検証することで認証ができる。 “sub” クレームがユーザーIDを指す。 検証方法の詳細は https://developers.google.com/identity/openid-connect/openid-connect?hl=ja#validatinganidtoken などを参照。

Slide 48

Slide 48 text

自前でアクセストークンとIDトークンを扱ってみよう 48 アクセストークンを使い userinfoエンドポイントから認証されたユーザーの 情報を取得する

Slide 49

Slide 49 text

紐解いてみるとOmniAuthなしでもできる 49 with OmniAuth without OmniAuth

Slide 50

Slide 50 text

OmniAuthは魔法じゃない 裏側で認証・認可のプロトコルに従った実装が されている まとめると 知ってるとお得

Slide 51

Slide 51 text

おまけ:明日から使えるTips (5)

Slide 52

Slide 52 text

OmniAuth.config.test_mode

Slide 53

Slide 53 text

OmniAuth.config.test_mode 53 https://github.com/omniauth/omniauth/wiki/Integration-Testing 外部のIDプロバイダを用意しなくても テストできる便利機能 AuthHashをモックする公式の方法

Slide 54

Slide 54 text

OmniAuth Setup Phase

Slide 55

Slide 55 text

OmniAuth Setup Phase 55 https://github.com/omniauth/omniauth/wiki/Setup-Phase Request Phaseに入る前に ストラテジの設定を動的に変更できる 例では /auth/openid_connect?type=sign_up というように type パラメータ付きで 開始したときに認証フローの挙動を変更

Slide 56

Slide 56 text

🙄 OAuth認証?

Slide 57

Slide 57 text

OAuth認証?? 57 omniauth-facebook OAuthだけだとアクセストークンしか得られないため、 そのアクセストークンを用いてユーザー情報APIから user_idを取得している → ユーザー認証を行いたい場合は omniauth/omniauth_openid_connect を使おう   IDトークンのsubクレームをもとに uid を決定してくれる https://github.com/simi/omniauth-facebook/blob/902971d18b4f43cfb1d969139b4a75bb517a055b/lib/omniauth/strategies/facebook.rb#L59

Slide 58

Slide 58 text

fin.

Slide 59

Slide 59 text

・物足りない方 ・興味を持っていただいた方

Slide 60

Slide 60 text

STORES 株式会社 の紹介 60 ● お店の運営を支えるプロダクト群 (ECの会社 じゃないよ) ● アカウント統合・データ統合たくさん ● 2025年は新規プロダクト +10 !