Slide 1

Slide 1 text

freee のマイクロサービス化 を⽀える InternalSession 横塚 直 2023年4⽉16⽇

Slide 2

Slide 2 text

ここに円に切り抜いた画像を入れてく ださい 横塚 直 2022年新卒⼊社。 配属後はサービス基盤で、共通ライブラリや ミドルウェアの実装を担当しています。 サービス基盤エンジニア

Slide 3

Slide 3 text

  お題⽬ Ruby on Rails の セッション管理実装 freee における セッション管理実装 セッション管理の課題 と InternalSession 01 02 03

Slide 4

Slide 4 text

freee のプロダクトラインアップ freee会計 freee開業 freee福利厚⽣ freeeアプリストア freee⼈事労務 freee会社設⽴ freee受発注 freeeプロジェクト管理 freee資⾦調達 freee申告 freeeカード

Slide 5

Slide 5 text

freee の “プロダクト” とは ● freee が提供するプロダクトの⼤部分は Web アプリケーション ● Web アプリケーションは HTTP リクエストに対してレスポンスを 返すことによって動作する freee のサーバー freee 会計のホーム 画面出して下さい! 確定申告のページ 出して!

Slide 6

Slide 6 text

Web アプリではセッション管理が必要 ● HTTP はステートレス ○ ログイン状態を保持できない ● 特定のクライアントからの⼀連の HTTP リクエストの間で情報を 共有する仕組みが必要 セッション管理なしではユーザーが認証されていることを 確認することが困難 イマドキの Web アプリではほぼ必須!

Slide 7

Slide 7 text

セッション情報の具体例 ● ログインユーザーのID ● テナントID ○ freee では事業所のID ● セッション情報の作成⽇時 { "user_id": 5135567, "created_at": "2023-04-01 19:57:07 +0900" }

Slide 8

Slide 8 text

セッション管理の⼀般的な実装 Ruby on Rails にはセッション管理の実装が⼤きく分けて2種類ある   ソースコード ● ActionDispatch::Session::CookieStore ● ActionDispatch::Session::CacheStore CookieStore CacheStore

Slide 9

Slide 9 text

CookieStore vs CacheStore CookieStore CacheStore セッション情報の 保存場所 Cookie データベース (Redis 等のKVS) Cookie に保存する 情報 セッション情報そのもの セッションID

Slide 10

Slide 10 text

CookieStore vs CacheStore 〜具体例〜 Set-Cookie: _techday_playground_session=ta%2BbFJv9Rdg0oyUvjTHdDrS8zmh61ky%2B8s3RosaItNQWKUJaJH6ZiqJWF1rT z4%2Bskb3nLmojuVL9JarpbVpxcaJ61P184x3JQ68DXE2nTyc9MP2U9hZLFVcbzjuTCq2VdMOQvuaA80D%2FuS1fnDmj 0CkFT3iAH3hR9tIOJEX9TKb8ysIvnxcsMAOKs5M0Zj2V5CbPiqqeLhpl%2FyhMv%2BbiYdfc1763yGwo8h0qkQ3nXIe7 yRTwXw07ETPyLHKggisLo0as0WhqmhZoP66xvnfiQ%2BftXHb6onLecVWyuzfUU8FMf0GnUYU4W43%2BB67NsR%2FK5z eG1r9dqfS6GkYmsj4MsbWl00qnKsOU0vPXejkezZ6E1u6tC4Ni7D2plfgORUzQ%2FNX1cY4ccTJWqmtcE9gL%2FlcKsa jdxUw143ksIGGPmqIwf0%2BR4UUUh5o6qm8DRmMtSZo2hUPxi8%2BFUKEAFZhKq1p5HGTESp%2Bfgcv2QKItvmpgZDv5 mUYVB3rKzINO8gmx1mIL4WgccEs2%2Bd5a%2FNxB6poXAjxFhZrx2cQykCkqt1g%3D--q9T9QbmdBvz%2FNG00--Uj0m Ph1muIKueQsw545Stg%3D%3D; path=/; HttpOnly; SameSite=Lax Set-Cookie: _session_id=03c49969faae6e6a187b0ecdcc203c2d; path=/; HttpOnly CookieStore CacheStore

Slide 11

Slide 11 text

CookieStore vs CacheStore 〜Pros & Cons〜 CookieStore CacheStore Pros 外部リクエスト不要 Revoke が容易 Cons Revoke が難しい DBアクセスがオーバーヘッド になる CookieStoreは、Railsで推奨されているデフォルトのセッションストアであり、例外的に すべてのセッションデータをcookie⾃⾝に保存します(必要に応じてセッションIDも利⽤ 可能です)。CookieStoreには⾮常に軽量であるというメリットがあり、新規Webアプリ ケーションでセッションを利⽤するための準備も不要です。 Rails ガイド ActionController の概要 5 セッション

Slide 12

Slide 12 text

CookieStore vs CacheStore 〜Revoke〜 ● Revoke = 取り消し ● CacheStore の場合、セッション情報はサーバーサイドに保存される ので、セッションIDが漏洩した場合はデータベースの管理者権限があ れば容易に取り消せる ● ⼀⽅で、CookieStore はセッション情報をクライアントサイドに保存 するため、取り消しは難しい

Slide 13

Slide 13 text

freee のセッション管理実装 〜概略〜 ● Ruby on Rails における CacheStore の実装に近い ● セッション情報そのものは Redis に保存して、Cookie には セッションIDを保存する ● セッション管理を担当する共通の認証サーバーがいる サービスB サービスC サービスA 認証サーバー

Slide 14

Slide 14 text

freee のセッション管理実装 〜シーケンス〜

Slide 15

Slide 15 text

freee のセッション管理の課題 サービスA ①リクエスト ②リクエスト ③レスポンス ⑧レスポンス ④リクエスト ⑤レスポンス ⑥リクエスト ⑦レスポンス サービスD サービスC サービスB ● システムが⼤きくなってこんな感じに...

Slide 16

Slide 16 text

● 都度都度、認証サーバーへのリクエストが必要 freee のセッション管理の課題 サービスA ①リクエスト ②リクエスト ③レスポンス ⑧レスポンス ④リクエスト ⑤レスポンス ⑥リクエスト ⑦レスポンス サービスD サービスC サービスB 認証 サーバー

Slide 17

Slide 17 text

マルチサービスにおけるセッション管理のツラミ ● 認証サーバーへ負荷がかかる ● 認証サーバーへのリクエストがオーバーヘッドになる ● クライアント側からの1リクエストに対して複数回認証サーバーに アクセスするのは無駄が多いようにも思える 今後のサービス数の増加や マイクロサービス化を考えると セッション管理がボトルネック になるかもしれない

Slide 18

Slide 18 text

そこで登場するのが InternalSession ● 内部通信におけるセッション管理を効率化する仕組み ○ サービス基盤チームで開発‧導⼊中 ● どんな仕組みか? ○ セッション情報をエンコードして⽣成したトークンを HTTP ヘッダーに付与する ○ ※内部通信でのみ使⽤可能 セッション情報を丸ごとやりとりする CookieStore に似た仕組み

Slide 19

Slide 19 text

The Structure of InternalSession ● “.” 区切りの⽂字列で3つのパートからなる ○ ヘッダー ○ ペイロード ○ 署名 ● ペイロードはセッション情報そのもの、署名は改竄防⽌⽬的で付与 “EgVlY2RzYQ==.Cg4KDAiM4qChBhCUjszqAQ==.MEUCIQCXvGZSJGlY uBhP8wLzWMqc3Bcp5GqPqzIMru2fwwl5OgIgCZ28dxlybF9VfyWfS1 +oHNsxUOdLMeyaNutOjtztSRA=” セッション情報を含んだ文字列を HTTP ヘッダに付与する JWT (JSON Web Token) と似た構造

Slide 20

Slide 20 text

InternalSession 導⼊前 再度認証サーバーに アクセス

Slide 21

Slide 21 text

InternalSession 導⼊後 内部通信の前に生成 認証サーバへアクセス不要

Slide 22

Slide 22 text

InternalSession vs 既存のセッション管理 InternalSession 既存のセッション管理 Pros 認証サーバーへの リクエスト不要 Revoke が容易 Cons Revoke 不可 認証サーバーへの アクセス回数多 CookieStore vs CacheStore と 同じようなトレードオフがある!

Slide 23

Slide 23 text

CookieStore vs CacheStore 〜Pros & Cons〜 the CookieStore - which stores all session data in the cookie itself (the ID is still available to you if you need it). This has the advantage of being very lightweight, and it requires zero setup in a new application to use the session. https://guides.rubyonrails.org/action_controller_overview.html#session CookieStore CacheStore Pros 外部リクエスト不要 Revoke が容易 Cons Revoke が難しい DBアクセスがオーバーヘッド になる

Slide 24

Slide 24 text

つまりどういうことか? ● セッション情報を丸ごとやりとりする InternalSession や CookieStore は早くて外部への依存もないが、Revoke が難しい ● セッション情報を都度問い合わせるようにすると、Revoke は 容易だがパフォーマンス問題を引き起こす可能性がある 外部との通信でやりとりするのはセッションIDにして、 freee 内部の通信ではセッション情報をそのままやりとりする。 パフォーマンスとセキュリティを両⽴を狙った施策が InternalSession

Slide 25

Slide 25 text

まとめ ● Webアプリケーションにおいてはセッション管理が必須 ● Ruby on Rails の2つのセッション管理実装には、パフォーマンスと セキュリティのトレードオフが存在する ● freee においては都度都度認証サーバーに問い合わせる形式を採⽤ していたが、サービス数の増加等を⾒据えるとボトルネックになる 可能性が想定された ● 対抗策として、InternalSession の開発導⼊を進めている

Slide 26

Slide 26 text

No content