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
2
680
PHP で学ぶ OAuth 入門
PHPカンファレンス小田原2025 の発表資料です。
SAW
April 12, 2025
Tweet
Share
More Decks by SAW
See All by SAW
React Hook Form と Zod によるフォームバリデーション
azuki
0
10
PHP で form-data を POST 以外のメソッドで受け取るには?
azuki
0
22
EditorConfig を使ってみよう
azuki
1
88
Symfony でサクッと作る REST API サーバー
azuki
1
190
Vite の Library Mode を使って Vue のコンポーネントをライブラリ化する
azuki
1
250
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
2
330
Provide/Inject で TypeScript の恩恵を受ける方法
azuki
3
150
GraphQL はいいぞ! ~Laravel で学ぶ GraphQL 入門~
azuki
1
370
OSS contributor への第一歩を踏み出すまでの物語
azuki
2
340
Other Decks in Programming
See All in Programming
Module Proxyのマニアックな話 / Niche Topics in Module Proxy
kuro_kurorrr
0
2.5k
Dive into Triton Internals
appleparan
0
460
KoogではじめるAIエージェント開発
hiroaki404
1
390
Introducing RemoteCompose: break your UI out of the app sandbox.
camaelon
2
500
Vueのバリデーション、結局どれを選べばいい? ― 自作バリデーションの限界と、脱却までの道のり ― / Which Vue Validation Library Should We Really Use? The Limits of Self-Made Validation and How I Finally Moved On
neginasu
3
1.8k
What's New in Web AI?
christianliebel
PRO
0
120
AI POSにおけるLLM Observability基盤の導入 ― サイバーエージェントDXインターン成果報告
hekuchan
0
320
マンガアプリViewerの大画面対応を考える
kk__777
0
460
テーブル定義書の構造化抽出して、生成AIでDWH分析を試してみた / devio2025tokyo
kasacchiful
0
400
HTTPじゃ遅すぎる! SwitchBotを自作ハブで動かして学ぶBLE通信
occhi
0
220
What’s Fair is FAIR: A Decentralised Future for WordPress Distribution
rmccue
0
130
業務でAIを使いたい話
hnw
0
240
Featured
See All Featured
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
37
2.6k
Build The Right Thing And Hit Your Dates
maggiecrowley
38
2.9k
Agile that works and the tools we love
rasmusluckow
331
21k
Code Review Best Practice
trishagee
72
19k
KATA
mclloyd
PRO
32
15k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.1k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
8k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
658
61k
Why Our Code Smells
bkeepers
PRO
340
57k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
253
22k
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
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠