Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PHP で学ぶ OAuth 入門
Search
SAW
April 12, 2025
Programming
1.4k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PHP で学ぶ OAuth 入門
PHPカンファレンス小田原2025 の発表資料です。
SAW
April 12, 2025
More Decks by SAW
See All by SAW
Effortless API Documentation with Scribe
azuki
0
73
Laravelで手軽にAPIドキュメントを生成する ― Scribe活用術
azuki
0
39
🪝 便利な Property Hooks を 使ってみよう 🪝
azuki
0
78
決済システム超初心者が Stripe に入門している話
azuki
0
110
React Hook Form と Zod によるフォームバリデーション
azuki
0
72
PHP で form-data を POST 以外のメソッドで受け取るには?
azuki
0
84
EditorConfig を使ってみよう
azuki
1
120
Symfony でサクッと作る REST API サーバー
azuki
1
270
Vite の Library Mode を使って Vue のコンポーネントをライブラリ化する
azuki
1
380
Other Decks in Programming
See All in Programming
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
190
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
260
Semantic Version 単位で戦略を柔軟に変えて、パッケージアップデートを自動化する
daitasu
0
220
CSC307 Lecture 17
javiergs
PRO
0
320
Modding RubyKaigi for Myself
yui_knk
0
920
AI時代の仕事技芸論 — ソフトウェア開発で「遊ぶように働く」職人的熟達のすすめ
kuranuki
2
660
AutonomyとControlのあいだ:Graflowで記述するAIエージェント協調
myui
0
120
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
160
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
110
LLM Plugin for Node-REDの利用方法と開発について
404background
0
170
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
150
AIで効率化できた業務・日常
ochtum
0
120
Featured
See All Featured
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
200
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
240
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
[SF Ruby Conf 2025] Rails X
palkan
2
1.1k
ラッコキーワード サービス紹介資料
rakko
1
3.6M
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.9k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.6k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.6k
How to Ace a Technical Interview
jacobian
281
24k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
160
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
Transcript
1)1ͰֶͿ0"VUIೖ 1)1ΧϯϑΝϨϯεখాݪ 4"8
$(whoami) w ࢯ໊Ճ౻फҰ ࡀ w ϋϯυϧωʔϜ4"8 w 9 چ5XJUUFS
!B[VLJ@FBUFS w ؔͷ*5ΤϯδχΞίϛϡχςΟͷ͔͠ ࣗশ w େࡕࡏॅɾѪग़ w ಘҙ8FCΞϓϦέʔγϣϯ։ൃ w -BSBWFM 7VF w ॴଐ༗ݶձࣾΞϦʔϓ 2 چ+*4ϚʔΫ ⁴ ͕ ਓͷԣإʹݟ͑ͨͷ ͚ࣗͩͰͳ͍ͣ ࠓͷ໎ݴ
ඵએ w 1)1ΧϯϑΝϨϯεؔਆށͰ։࠵ w ۚ ɾ w
։࠵ॴਆށӺલݚमηϯλʔ w ઈࢍϓϩϙʔβϧืूத w క ·Ͱ w εϙϯαʔืूத 3 ϓϩϙʔβϧืूϑΥʔϜ εϙϯαʔืूࢿྉ
͜ͷτʔΫͷ֓ཁͱඪ w ೝՄٕज़ͷͭͰ͋Δ0"VUIͷجૅΛઆ໌ w ೝূɾೝՄͷجૅ w 0"VUIͱԿ͔ w 0"VUIͷ͍Ͳ͜Ζ w
؆୯ͳ࣮ྫΛަ͑ͨ0"VUIͷೝՄॲཧͷઆ໌ w ඪ0"VUIͷجૅతͳॲཧͷྲྀΕΛ௫Ή w ʮখాݪͰΈΜͳͰֶ΅͏0"VUIʯˠʮখాݪͰجૅΛֶΜͩ0"VUIʯ 4
ຊτʔΫͷରൣғͱରऀ w ରൣғ0"VUIͷ"VUIPSJ[BUJPO$PEFͷΈ͕ର w جຊతͳॲཧϑϩʔΛத৺ʹઆ໌ w ࣮ફతͳ༰ৄࡉͳ༷ର֎ w ଞͷೝՄ༩ํࣜ *NQMJDJU
$MJFOU$SFEFOUJBMͳͲ ൣғ֎ w ରऀ0"VUIͷجૅʹڵຯͷ͋Δํ w 0"VUIʹ৮Εͨ͜ͱ͕ͳ͍ํ 5
͓͢͢Ίͷࢀߟॻ w 0"VUIపఈೖηΩϡΞͳೝՄγεςϜΛద༻͢ΔͨΊͷݪଇͱ࣮ફ w +VTUJO3JUDIFS "OUPOJP4BOTPஶɾਢాஐ೭༁ ᠳӭࣾ w 0"VUIͷجૅ͔ࣝΒؔ࿈ٕज़·Ͱ৮ΕΒΕ͍ͯΔ w
࣮ྫॆ࣮ ࣮ݴޠ+BWB4DSJQU w ͜ΕҰͰ͔ͳΓֶΔ 6
ೝূɾೝՄͱ0"VUI 7
ೝূͱೝՄ w ೝূ "VUIFOUJDBUJPO w γεςϜʹొ͞Ε͍ͯΔϢʔβʔͷຊਓΛ֬ೝ͢Δॲཧ w ྫ4/4&$αΠτͳͲͷ8FCγεςϜͷϩάΠϯ w
γεςϜʹొ͞Ε͍ͯΔϢʔβʔใͱ߹க͢Δ͜ͱͰγεςϜ͕ར༻Ͱ͖Δ w ೝՄ "VUIPSJ[BUJPO w γεςϜͷػೳϦιʔεͷΞΫηεͷՄ൱Λ੍ޚ͢Δॲཧ w ྫ6/*9ͷϑΝΠϧγεςϜͷύʔϛογϣϯ w ϑΝΠϧͷૢ࡞͕ͦͷϢʔβʔʹରͯ͠ڐՄ͞Ε͍ͯΔ߹ʹͷΈૢ࡞͕Մೳ 8
0"VUIͱ w 0"VUI8FCΞϓϦέʔγϣϯʹ͓͚ΔೝՄͷͨΊͷϓϩτίϧ w SEύʔςΟͷγεςϜ͔Β8FCαʔϏεʹΞΫηε͢Δ͜ͱΛೝՄ w ΞΫηετʔΫϯΛར༻ͯ͠8FCαʔϏεʹΞΫηε w ೝূʹؔ͢ΔϓϩτίϧͰͳ͍͜ͱʹҙ w
ڐՄ͞Εͨݖݶͷൣғ είʔϓ ͰͷΈΞΫηε͕Մೳ w ݖݶͷൣғ8FCαʔϏεͷར༻ऀ͕ڐՄͨ͠ൣғ 9
0"VUIͷར༻ྫ w ESBXJP͔Β(PPHMF%SJWFʹΞΫηε w ESBXJP8FC্Ͱ࡞ਤͰ͖ΔαʔϏε w (PPHMF%SJWF(PPHMFͷΫϥυετϨʔδαʔϏε w ESBXJP͕(PPHMF%SJWFʹٻΊΔΞΫηεݖͷྫ w
ετϨʔδͷϑΝΠϧͷಡΈࠐΈ w ετϨʔδͷϑΝΠϧͷอଘ 10 ESBXJP͔Β(PPHMF%SJWFͷ ΞΫηεͷೝՄΛཁٻ (PPHMF%SJWFͰΞΫηεݖͷೝՄΛ֬ೝ
ͳͥ0"VUI͔ w 8FCαʔϏεͷೝূใΛSEύʔςΟͷγεςϜͱڞ༗͠ͳ͍ w 8FCαʔϏεଆͷೝূใΛมߋͯ͠ӨڹΛड͚ͳ͍ w ͦͦηΩϡϦςΟతʹೝূใΛ֎෦γεςϜͱڞ༗ͨ͘͠ͳ͍ w SEύʔςΟͷγεςϜ͕ཁٻ͢ΔݖݶΛ֬ೝͰ͖Δ w
ཁٻ͞ΕΔݖݶͷ༰͕Ϣʔβʔʹࣔ͞ΕΔ w ϢʔβʔͷڐՄͳ͠ʹݖݶ͕༩͞ΕΔ͜ͱ͕ͳ͍ 11 ESBXJP͕ཁٻ͢Δ(PPHMF%SJWFͷݖݶͷ༰Λ Ϣʔβʔʹ֬ೝ͢Δྫ
0"VUIͷॲཧϑϩʔ 12
0"VUIʹ͓͚Δొਓ w ΫϥΠΞϯτ $MJFOU w อޢରϦιʔεʹΞΫηε͢ΔSEύʔςΟͷιϑτΣΞ w อޢରϦιʔε 1SPUFDUFE3FTPVSDF
w Ϧιʔεॴ༗ऀ͕ΞΫηεݖΛ࣋ͭػೳσʔλͳͲͷϦιʔε w Ϧιʔεॴ༗ऀ 3FTPVSDF0XOFS w อޢରϦιʔεͷΞΫηεݖΛͭϢʔβʔ w ೝՄαʔόʔ "VUIPSJ[BUJPO4FSWFS w Ϧιʔεॴ༗ऀ͕ΫϥΠΞϯτΛೝՄ͢ΔΈΛఏڙ͢ΔγεςϜ 13
ొਓͷ۩ମྫ w ΫϥΠΞϯτESBXJP w อޢରϦιʔε(PPHMF%SJWF"1* w Ϧιʔεॴ༗ऀϒϥβΛૢ࡞͍ͯ͠ΔϢʔβʔ w ೝՄαʔόʔ(PPHMFͷ0"VUIೝՄαʔόʔ 14
0"VUIͷॲཧϑϩʔ Ϧιʔεॴ༗ऀ͕ΫϥΠΞϯτΛೝՄ w ཁٻ͞ΕΔݖݶͷ༰ΛϦιʔεॴ༗ऀʹఏࣔͯ͠ೝՄ͢Δ͔֬ೝ ೝՄαʔόʔೝՄίʔυΛੜ ΫϥΠΞϯτೝՄίʔυ͔ΒΞΫηετʔΫϯΛऔಘ
ΫϥΠΞϯτΞΫηετʔΫϯΛར༻ͯ͠อޢରϦιʔεʹΞΫηε 15
0"VUIͷॲཧϑϩʔ 16 ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτ อޢରϦιʔε ΫϥΠΞϯτΛೝՄ
0"VUIͷॲཧϑϩʔ 17 ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτ อޢରϦιʔε ೝՄαʔόʔʹϦμΠϨΫτ ೝՄαʔόʔʹϦμΠϨΫτ
0"VUIͷॲཧϑϩʔ 18 ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτ อޢରϦιʔε ΞΫηεݖͷೝՄΛ֬ೝ
0"VUIͷॲཧϑϩʔ 19 ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτ อޢରϦιʔε ΞΫηεݖΛೝՄ
0"VUIͷॲཧϑϩʔ 20 ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτ อޢରϦιʔε ೝՄίʔυΛΫϥΠΞϯτʹ ϦμΠϨΫτ ೝՄίʔυΛ ΫϥΠΞϯτʹ
ϦμΠϨΫτ
0"VUIͷॲཧϑϩʔ 21 ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτ อޢରϦιʔε ೝՄίʔυΛ ૹ৴
0"VUIͷॲཧϑϩʔ 22 ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτ อޢରϦιʔε ΞΫηετʔΫϯΛ ൃߦ
0"VUIͷॲཧϑϩʔ 23 ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτ อޢରϦιʔε ΞΫηετʔΫϯΛਵͯ͠ อޢରϦιʔεʹΞΫηε
0"VUIͷॲཧϑϩʔ 24 ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτ อޢରϦιʔε ೝՄ͞ΕͨείʔϓͰ ϦιʔεΛฦ٫
ೝՄίʔυͱΞΫηετʔΫϯ w ೝՄίʔυΞΫηετʔΫϯΛಘΔͨΊͷҰ࣌తͳίʔυ w Ϧιʔεॴ༗ऀʹΑΔΫϥΠΞϯτͷೝՄͷ݁ՌΛࣔ͢ίʔυ w codeͱ͍͏ΫΤϦύϥϝʔλʔΛ༩ͯ͠ΫϥΠΞϯτʹϦμΠϨΫτ w ΞΫηετʔΫϯอޢରϦιʔεͷΞΫηεͰར༻͢ΔτʔΫϯ w
อޢରϦιʔεΞΫηετʔΫϯΛड͚औͬͯݖݶΛ֬ೝͯ͠ϦιʔεΛฦ͢ w อޢରϦιʔεΫϥΠΞϯτ͔Β#FBSFSτʔΫϯͰड͚औΔ 25
είʔϓ w อޢରϦιʔεͷΞΫηεݖΛࣔ͢จࣈྻ w ෳͷείʔϓۭനจࣈ۠ΓʹΑͬͯදݱ͞ΕΔ w ΫϥΠΞϯτ͕ΞΫηεͰ͖ΔൣғείʔϓͰࣔ͞ΕͨൣғͷΈ w Ϧιʔεॴ༗ऀ͕ೝՄ͍ͯ͠ͳ͍είʔϓͷϦιʔεʹΞΫηεෆՄ 26
֤ॲཧϑϩʔͷ࣮ྫ 27
࣮ྫʹ͍ͭͯ w -BSBWFMͷίʔυͷҰ෦Λར༻ͯ͠આ໌ w 8FCαʔόʔͷػೳͳͲ0"VUIͷຊ࣭Ͱͳ͍෦ͷ࣮Λ؆ܿԽ w ෦ॲཧΛӅณ͠ͳ͍ͨΊʹ0"VUIͷϥΠϒϥϦར༻͠ͳ͍ w ࣮ફతͳΞϓϦέʔγϣϯ։ൃͰ0"VUIͷϥΠϒϥϦΛ͏ํ͕ྑ͍ w
0"VUIͷ࣮ʹ͓͍ͯݴޠϑϨʔϜϫʔΫෆ w ཧղͷ͢͠͞Λ༏ઌ w όϦσʔγϣϯͳͲͷ࣮ફతͳ༰লུ 28
࣮ྫͷ֤ߏཁૉͷΞΫηε w Ϧιʔεॴ༗ऀਓؒ ϒϥβ w ΫϥΠΞϯτlocalhost:8000 w ೝՄαʔόʔlocalhost:8001 w
อޢରϦιʔεlocalhost:8002 29
ΫϥΠΞϯτͷೝՄཁٻ w Ϧιʔεॴ༗ऀΛೝՄαʔόʔʹϦμΠϨΫτ w ϦμΠϨΫτ࣌ʹೝՄରͷΫϥΠΞϯτͷใΛΫΤϦύϥϝʔλʹ༩ 30 $query = http_build_query([ 'response_type'
=> 'code', 'client_id' => env('CLIENT_ID'), 'redirect_uri' => 'http://localhost:8000/callback', 'scope' => 'file.read file.write', ]); $authEndpoint = Uri::new('http://localhost:8001/authorize') ->withQuery($query); return redirect()->away($authEndpoint); ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτ ೝՄαʔόʔʹ ϦμΠϨΫτ localhost:8000 localhost:8001 ༩ํࣜBVUIPSJ[BUJPODPEF ΫϥΠΞϯτ͕ཁٻ͢Δείʔϓ
ΫϥΠΞϯτͷೝՄͷ֬ೝ w ΫϥΠΞϯτΛೝՄ͢Δ͔Ϧιʔεॴ༗ऀʹ֬ೝ w είʔϓۭനจࣈ۠ΓͰΫΤϦύϥϝʔλͰ͞ΕΔ 31 $clientId = $request->query('client_id'); $client
= Client::find($clientId); // 要求されているスコープを取得 $scope = str($request->query('scope')) ->explode(' ')->filter(); return view('authorize', [ 'client' => $client, 'scope' => $scope, ]); ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτͷ ೝՄΛ֬ೝ localhost:8001
ΫϥΠΞϯτͷೝՄ w ೝՄίʔυΛൃߦͯ͠ΫϥΠΞϯτͷίʔϧόοΫ63-ʹϦμΠϨΫτ w ೝՄίʔυͱϦιʔεॴ༗ऀ͕ڐՄͨ͠είʔϓΛΫΤϦύϥϝʔλͱͯ͠༩ 32 $scope = $request->input('scope'); $authzCode
= Str::random(); $codes[$authzCode] = ['scope' => $scope]; Cache::put('codes', $codes); $callbackUrl = Uri::new($redirectUrl) ->withQuery([ 'scope' => $scope, 'code' => $authzCode, ]); return redirect()->away($callbackUrl); ೝՄαʔόʔ Ϧιʔεॴ༗ऀ ΫϥΠΞϯτ ΫϥΠΞϯτʹ ϦμΠϨΫτ localhost:8000 localhost:8001 ೝՄίʔυΛ༩
τʔΫϯͷऔಘ w ΫϥΠΞϯτೝՄαʔόʔʹೝՄίʔυΛૹ৴ w ΫϥΠΞϯτ#BTJDೝূͰࣝผ w ೝՄαʔόʔΫϥΠΞϯτʹΞΫηετʔΫϯΛൃߦ 33 ೝՄαʔόʔ ΫϥΠΞϯτ
ೝূใͱೝՄίʔυΛ ૹ৴ localhost:8000 localhost:8001 $clientId = $request->getUser(); $clientSecret = $request->getPassword(); $codes = Cache::get('codes'); $code = $codes[$request->input('code')]; // クライアントの情報と認可コードを検証 $token = Str::random(); AccessToken::create(['token' => $token]); return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer', 'scope' => $code['scope'], ]); ΞΫηετʔΫϯΛૹ৴ #BTJDೝূͰΫϥΠΞϯτΛࣝผ
อޢରϦιʔεͷΞΫηε w ΫϥΠΞϯτอޢରϦιʔεʹΞΫηετʔΫϯΛར༻ͯ͠ΞΫηε w ΞΫηετʔΫϯ#FBSFSτʔΫϯͰ͞ΕΔ w อޢରϦιʔεϦιʔεΛΫϥΠΞϯτʹฦ٫ w ೝՄ͞Εͨείʔϓ֎ͷΞΫηεڐՄ͠ͳ͍ 34
ΫϥΠΞϯτ ΞΫηετʔΫϯΛ༩ͯ͠ ϦιʔεʹΞΫηε localhost:8000 localhost:8002 Ϧιʔεͷ༰Λฦ٫ อޢରϦιʔε $token = $request->bearerToken(); $accessToken = AccessToken::whereFirst('token', $token); if ($accessToken?->scope->contains('file.read')) { $content = Storage::json('data.json'); return response()->json($content); } else { return response()->json(null, 403); } #FBSFSτʔΫϯ͔Β ΞΫηετʔΫϯΛऔಘ ΞΫηετʔΫϯʹཁٻ͞ΕΔ είʔϓ͕ଘࡏ͢Δ͔νΣοΫ
མึर͍ w ϦϑϨογϡτʔΫϯΞΫηετʔΫϯΛ࠶ൃߦ͢ΔͨΊͷίʔυ w ༗ޮظݶ͕Εͨ߹ͳͲʹϦιʔεॴ༗ऀʹೝՄΛٻΊΔ͜ͱͳ͘࠶ൃߦ w TUBUF$43'Λ͙ͨΊͷύϥϝʔλʔ w ೝՄίʔυͷૹ৴ݩ͕Ϧιʔεॴ༗ऀ͕ೝՄͨ͠ΫϥΠΞϯτͱಉҰ͔֬ೝ 35
্༷ඞਢͰͳ͍͕ɺηΩϡϦςΟϗʔϧʹͳΔͨΊ ࣄ্࣮ඞਢͷύϥϝʔλͱߟ͑ͨํ͕ྑ͍ ه
·ͱΊ w 0"VUIͷجૅʹ͍ͭͯઆ໌ w ೝূɾೝՄʹ͍ͭͯઆ໌ w 0"VUIͷ֓ཁͱ࣮ྫΛઆ໌ w 0"VUIͷೝՄॲཧϑϩʔʹ͍ͭͯઆ໌ w
֤ཁૉͷॲཧ༰Λ؆୯ͳ࣮ྫΛ༻͍ͯઆ໌ 36
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠