Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Firebase Authenticationのセッション管理術
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
SatohJohn
July 07, 2023
Programming
2.7k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Firebase Authenticationのセッション管理術
7/7 PORT Firebase meetup
https://connpass.com/event/285741/
発表させていただいた資料です
SatohJohn
July 07, 2023
More Decks by SatohJohn
See All by SatohJohn
Managed Agents API は Google Cloud の運用の夢を見ることはできるか?
satohjohn
0
37
BigQuery を検索ソースとした AI Agent の作り方って 〇〇 通りあんねん
satohjohn
0
250
Claude Codeで評価を楽にする
satohjohn
0
120
A2UI という光を覗いてみる
satohjohn
1
270
_Architecture_Modernization_から学ぶ現状理解から設計への道のり.pdf
satohjohn
2
1.4k
アーキテクチャモダナイゼーションを実現する組織
satohjohn
1
1.8k
Vertex_AI_Searchを使いこなす実践テクニック
satohjohn
1
330
アーキテクチャモダナイゼーションの書籍紹介
satohjohn
0
90
NVIDIA NeMo Agent Tooklit を使ってみた
satohjohn
0
190
Other Decks in Programming
See All in Programming
Getting Started with Vibe Coding
miccheng
0
180
Spec-driven Development with AI
simas
PRO
0
2.2k
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
510
Crash Auto Pipelines
veronikapj
1
350
Materialが消えた日 〜真っ白なFlutterキャンバスにRenderObjectで絵を描く〜
umigishiaoi
0
140
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
1.9k
baseline으로 마이그레이션, 리팩토링 안전하게 맡기기
fornewid
1
870
Optunaを作ったときにやりたかったこと、その後 (2026/10/16, Optuna Meetup #3)
iwiwi
4
1.4k
Coding with AI: How to trust the storyteller (AWS Community Day Adria, Ljubljana 2026)
slobodan
0
140
AI-Powered Domain-Driven Design
ziobrando
0
380
AIがコードを書いてくれる時代、我々は何を確かめるのか
yosuke_furukawa
PRO
13
5.6k
私なりのハーネスエンジニアリング ~独自の言語処理系の開発を通して~
seosoft
0
180
Featured
See All Featured
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
330
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.9k
Speed Design
sergeychernyshev
33
2.2k
Site-Speed That Sticks
csswizardry
13
1.6k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
2
2.1k
How to train your dragon (web standard)
notwaldorf
96
6.9k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
570
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
3.7k
[SF Ruby Conf 2025] Rails X
palkan
3
1.5k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Prompt Engineering for Job Search
mfonobong
0
570
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Transcript
Firebase Authenticationの セッション管理術 2023/07/07 PORT Firebase meetup 株式会社スリーシェイク 佐藤慧太
自己紹介 • 株式会社スリーシェイク Sreake事業部 • 佐藤慧太@SatohJohn • SREとしてお客様の労苦<Toil>を減らす仕事 • Google
Cloudの製品が好き • FirebaseでのWebアプリケーション経験4年ぐらい
株式会社スリーシェイクについて Copyright © 3-shake, Inc. All Rights Reserved. xOps
Plattform DesignOps IaaS DevOps / SRE RevOps (Revenue Ops) HR(Engineer Hiring) HROps Data Engineering DataOps Security DevSecOps SecOps 事業者が抱える セキュリティリスクを無くす 本格的な脆弱性診断を 無料で手軽に セキュリファイ Security 良いエンジニアに良い案件を フリーランスエンジニアに 「今よりいい条件」を リランス HR(Engineer Hiring) あらゆるサービスを連携する ハブになる クラウド型ETL/データパイプ ラインサービスの決定版 レコナー Data Engineering 日本のSREをリード SRE総合支援からセキュリティ 対策を全方位支援 スリーク SRE スリーシェイク = xOps領域のプラットフォーマーへ
Session管理って めんどくさいですよね?
本日伝えたいこと • Webアプリケーションでの Firebase Authenticationのセッション管理方法について ◦ Cookie ◦ idTokenとService Worker
本日伝えたいこと • Webアプリケーションでの Firebase Authenticationのセッション管理方法について ◦ Cookie ◦ idTokenとService Worker
実装できる(気がする)まで持っていく
話さないこと • Service workerの詳しい説明 ◦ fetchしかでてきません • Firebase Authenticationの詳しい説明 ◦
Login後のどう管理するかだけです
超概略的まとめ • idTokenはaccess tokenのようなもので、有効期限がとても短い • idTokenをcookieに変換して利用する ◦ サーバ側で検証、処理をするイメージ • service
workerを使って、idTokenのまま利用する ◦ フロント側で検証、処理をするイメージ
Cookieの利用
Cookieでの管理のメリット • ブラウザが保存、取り出しをしてくれるため フロントで処理を記載する必要がない • 初回アクセス時にサーバ側で処理できる • 古いブラウザでも対応している
Cookieでの管理のデメリット • Cookieの作成の口を用意しないといけない • 色々なアプリで展開している場合、Cookie用の検証用の口を サーバサイドで用意しないと行けない • 他Firebase製品をフロントで使う場合や、Password変更など 組み合わせる際に、セッション管理が別になり、複雑になる
Cookieシーケンス Login部分 • Firebaseでのログインをした後 idTokenを取得する • idTokenをもとにCookieを サーバで作成してもらう • ログイン状態の2重管理になるた
め以下を注意する ◦ Firebase Authentication の情報保存をoffにするこ と ◦ Cookieの保存後に Firebase Authentication でログアウトすること
Cookieシーケンス Login部分 • Firebaseでのログインをした後 idTokenを取得する • idTokenをもとにCookieを サーバで作成してもらう • ログイン状態の2重管理になるた
め以下を注意する ◦ Firebase Authentication の情報保存をoffにするこ と ◦ Cookieの保存後に Firebase Authentication でログアウトすること
実装(フロント) • ログイン方法は別になんでもよく idTokenが取得できれば良い • Cookie取得のリクエストが成功す ればCookieが自動的に ブラウザに保存される import {
signInWithEmailAndPassword, } from "firebase/auth"; export const loginWithEmailAndPassword = (auth, email, password) => { return signInWithEmailAndPassword(auth, email, password) .then(async (result) => { const idToken = await result.user.getIdToken(); return login(idToken); }) }; export const login = (idToken) => { return fetch("/auth/authenticate", { method: "POST", data: { id_token: idToken, }, }).then((data) => data.json()) };
実装(サーバ) • フロントから送られてきたidToken を使ってCookieを 組み立てる • CookieにHTTP OnlyとSecure属 性をつけることを忘れない def
authenticate(request): id_token = request.POST.get("id_token") if id_token is None or len(id_token) == 0: return HttpResponse("id token not found", status=400) session_cookie = create_session_cookie(id_token) if session_cookie is None: return HttpResponse("Failed to create a session cookie", status=401) response = HttpResponse() response.set_cookie( session_cookie["name"], value=session_cookie["value"], expires=session_cookie["expires"], secure=True, httponly=True, samesite="Lax", ) return response
実装(サーバ) • idTokenをデコードすると認証した 時間が取れる • 認証した時間から公式では 5分以内であることで不正ではな いことを担保している • Cookieで使える値は最大14日間
の有効期限なのでCookieもその 時点で消えるようにしておく from firebase_admin import auth def create_session_cookie(id_token): decoded_claims = auth.verify_id_token(id_token) if time.time() - decoded_claims["auth_time"] < 5 * 60: expires_in = datetime.timedelta(days=14) expires = datetime.datetime.now() + expires_in session_cookie = auth.create_session_cookie(id_token, expires_in=expires_in) return build_session_cookie(expires, session_cookie) return None def build_session_cookie(expires, session_cookie): return {"expires": expires, "value": session_cookie, "name": LOGIN_COOKIE_NAME}
cookieシーケンス リクエスト部分 • ブラウザがリクエスト時にCookie をつける • 検証結果に応じて処理を 実施する
実装(サーバ) • Cookieからclaim取得して それからUserを取得する • userが取得できない場合は 403エラーとしても良いし 未ログインでも使えるように してもよい •
Pythonの例ではあるが FrameworkのMiddleware上で 実装するのが良い class RequiredAuthorizedMiddleware: get_response = None REQUIRED = "required" KEY = "auth" REQUIRED_DICT = {KEY: REQUIRED} def __init__(self, get_response): self.get_response = get_response def process_view(self, request, view_func, view_args, view_kwargs): claim = auth.verify_session_cookie(request.COOKIES.get(LOGIN_COOKIE_NAME)) if self.authorized(claim, request): request.login_user = convert_login_user(claime) return None return HttpResponse("fobidden", status=403) def authorized(self, claim, request): if claim is None: return False return True
idTokenとservice worker
idTokenとservice workerのメリット • 作成の変換コストがcookieより少ない • client、Firebase間でidTokenの更新をするため、サーバ側での期限切れがパ ターンが少ない • idToken作成に使うrefresh tokenがcookieよりも生存する期間が長いため
再度Loginページ表示が少なくて済む • iOS、Androidと同じような処理で、サーバ側で認証ができる
idTokenとservice workerのデメリット • idTokenの期限が1時間なので、作り直しはcookieより多い • 古いブラウザなどでService Workerに対応していない可能性がある • 初回アクセス時にサーバ側で処理しないため、要件とは合わない可能性がある
service worker シーケンス • Cookieのときと、ログインまでは 変わらない • HTMLを受け取りservice worker を、インストールする部分が入って
いる
実装(フロント) • Firebase Authenticationで ログインをするだけ import { signInWithEmailAndPassword } from
"firebase/auth"; export const loginWithEmailAndPassword = (auth, email, password, afterLogin) => { return signInWithEmailAndPassword(auth, email, password) .then(async (result) => { return afterLogin(); }) };
service worker シーケンス • idTokenが取得できない場合は Loginページに遷移させる ◦ サーバで処理する場合も 検証は必要なので 2箇所見る必要がある
実装(フロント) • getIdTokenの際にtokenが取得で きるかをみて リダイレクトさせる • httpRequestの際にリクエストをプ ロキシすることができるので同じ ホストの場合 Headerに追加する
• 公式で公開されているコードがあ るのでそちらを見ながら 触ってみると良いかと self.addEventListener("fetch", (event: Event) => { const fetchEvent = event as FetchEvent; const requestProcessor = (idToken: string | null) => { let req = fetchEvent.request; let processRequestPromise = Promise.resolve(); if (self.location.origin == getOriginFromUrl(fetchEvent.request.url)) { const headers = new Headers(); for (let entry of req.headers.entries()) { headers.append(entry[0], entry[1]); } headers.append("Authorization", "Bearer " + idToken); processRequestPromise = getBodyContent(req).then((body) => { req = new Request(req.url, { method: req.method, headers: headers, mode: "same-origin", credentials: req.credentials, cache: req.cache, redirect: req.redirect, referrer: req.referrer, body: body as string, }); }); } return processRequestPromise.then(() => fetch(req)); }; fetchEvent.respondWith(getIdToken().then(requestProcessor)); });
実装(サーバ) • headerからidTokenを取得し フロントで行えないユーザ別の処 理を行う事ができる • この形はアプリでも同じ形に なるはず function getIdToken(req)
{ const authorizationHeader = req.headers.authorization || ''; const components = authorizationHeader.split(' '); return components.length > 1 ? components[1] : ''; } app.get("/something", (req, res) => { const idToken = getIdToken(req); admin .auth() .verifyIdToken(idToken) .then((decodedClaims) => { return res.json(something(decodedClaims)) }) .catch((error) => { console.log(error); res.status(403); res.json({ error: "You must be logged in to continue!" }); }); });
実装(フロント) • サーバとの通信とは関係なく ログイン中のユーザの情報を 取得できる • ログイン中のユーザ情報はauthイ ンスタンスから取得する ◦ idTokenから取得できるレ
ベルではある export const getLoginUser = (auth): Promise<User | null> => { return new Promise((resolve, reject) => { const subscribe = auth.onAuthStateChanged((user) => { subscribe(); resolve(user); }); }); };
まとめ • どっちが良いということはなく、サービスの特性に合わせて利用する ◦ idTokenをcookieに変換して利用する ▪ 処理をサーバで実施するようなパターン ▪ MPAのアプリケーションと相性が良い ◦
service workerを使って、idTokenのまま利用する ▪ 処理をフロントで実施するようなパターン ▪ SPAのアプリケーションと相性が良い
一緒にSREとして働きませんか? • 社会から労苦<Toil>をなくしましょう ◦ 気になりましたら会社ホームページやどんなメンバがいるのか を見ていただき 申し込みしていただければ! ◦ または、私の方にtwitterとかでメンションなどでご相談していただければ!
おわり