簡單易懂的 OAuth 2.0

簡單易懂的 OAuth 2.0

Note: 300+ Pages ,推薦下載 PDF

這年頭不管什麼 app 都要串別人的 API ,但如果你要造 API 給別人串,除了規劃 endpoint 和 JSON 資料結構之外,還有更重要的「存取管制」,以及「user 的存在」,例如,你會希望 API request 可以知道「要改哪個 user 的資料」,但不希望 client 儲存 user 的帳號密碼。

利用 OAuth 2 通訊協定,可以實作出 API 的存取管制,讓 API 得知要操作的對象 user 是誰,並且讓你做出像 Facebook 登入那樣子的登入流程。然而 OAuth 2.0 的 spec 根本就是個 [tl;dr] 的東西,但沒讀過 spec 也沒辦法輕鬆實作,更別說套現成的 gem 擋在 API 的前面。本演講會簡單介紹 OAuth 2 是怎麼一回事,並示範如何從零建立一個用 OAuth 2 鎖住的 Grape API。若您沒有 Ruby / Rails 的經驗,也可以大略得知製造 OAuth 2.0 API 鎖的方法。

延伸閱讀:

* 我 Blog 裡面的 OAuth 2 相關文章 http://blog.yorkxin.org/tags/OAuth
* Demo 的簡單 OAuth 2 Guard 實作 https://github.com/chitsaou/oauth2-api-sample

36b1f565fc83d9b67588123f2171b896?s=128

Yu-Cheng Chuang

November 26, 2013
Tweet

Transcript

  1. ᾏẪၞ׭֥ OAuth 2 ⇯௾ 2013/11/26, Ruby Tuesday Taipei #27 (?)

  2. • ⇯௾č⊫ტӵĎ • Rails Developer at KKBOX, working at the

    KKTIX team • chitsaou, @yorkxin, blog.yorkxin.org
  3. Today’s Target • ୆὜ᆩ֡ OAuth 2 Protocol ᄸ喁஝ • ୆὜ु֤׭

    99% ࠎᧄ OAuth 2 ֻ֥೘ٚ API ໓ࡱ • ୆὜ᆩ֡ᄸ喁Ⴈ OAuth 2 ⅞୆֥ API
  4. Agenda • OAuth 2 ൞മ喁ĤॖၛଦῲἓખĤ • OAuth 2 ๙⇫⇐קᄸ喁஝ •

    ⚧ᄯ OAuth 2 Provider ֥ٚم • ֻ၂ՑႨ Rails + Grape API ᆜކ OAuth 2 ࣼഈ൭
  5. OAuth 2 ൞മ喁ĤݺӹĤ

  6. OAuth 2.0 • ಆ଀ “The OAuth 2.0 Authorization Framework” •

    Authorization (n.) ൱⃴
  7. ದ ๩Ἶ¯¯ ൱⃴ἡ ӱൔ 䪌w୆ॖၛಀ۵ଛᅟଦ໡֥⊷ਘx

  8. ದ ๩Ἶ¯¯ ൱⃴ἡ ӱൔ 䪌w୆ॖၛಀ۵ଛᅟଦ໡֥⊷ਘx User

  9. ದ ๩Ἶ¯¯ ൱⃴ἡ ӱൔ 䪌w୆ॖၛಀ۵ଛᅟଦ໡֥⊷ਘx User App

  10. ದ ๩Ἶ¯¯ ൱⃴ἡ ӱൔ 䪌w୆ॖၛಀ۵ଛᅟଦ໡֥⊷ਘx User Website App

  11. ದ ๩Ἶ¯¯ ൱⃴ἡ ӱൔ 䪌w୆ॖၛಀ۵ଛᅟଦ໡֥⊷ਘx User Website App API

  12. ದ ๩Ἶ¯¯ ൱⃴ἡ ӱൔ 䪌w୆ॖၛಀ۵ଛᅟଦ໡֥⊷ਘx User Website App API Sounds

    Familiar?
  13. You Facebook  API ದ ๩Ἶ¯¯ ൱⃴ἡ ӱൔ 䪌w୆ॖၛಀ۵ଛᅟଦ໡֥⊷ਘx Sounds

    Familiar?
  14. The Old-School Way… • App ေ୆℻ೆ≷ὂૡđὕ℥ૼ҂὜⁙۞ • ୆ေྐ಩ App ҂὜ଦ୆֥ૡ⁙۞

    • ࣼෘ App ޓܭđФἓሼὕ൞㢻ࣷ • ҂ܵ୆ྐ҂ྐđ໡ّᆞ൞҂ྐ……
  15. OAuth ೂޅࢳ㢯≾ἠ↜ⅳ • ↌ᅟิ܂ܲٚࢸ૫đ⃸୆ॖၛ൱⃴ӱൔ൐Ⴈ⊷ਘ • ӱൔթ֥൞ Token ط٤≷ὂૡ
 ္Ⴈ Token

    ಀյ API • Token ॖၛἲקթ౼ữ↏čscopes, ೂğݺႶਙіĎ • Token Ⴕ௹ཋط౏ॖၛ⅗ℭӜ⇍č҂ஃФἓሼĎ
  16. OAuth 2 䥰૫֥࢘೤ • Resource Owner - ⊷ਘ∭Ⴕᆀđ๙ӈ൞ದ  (User) •

    Client - ࠧ App đေթ౼ User ֥⊷ਘ֥ӱൔ • Authorization Server - ⊺ܵ၂్൱⃴൙↩ • Resource Server - Client ạ≾䥰ଦ⊷ਘđࠧ API
  17. ದ ๩Ἶ¯¯ ൱⃴ἡ ӱൔ 䪌w୆ॖၛಀ۵ଛᅟଦ໡֥⊷ਘx You Facebook  API

  18. ದ ๩Ἶ¯¯ ൱⃴ἡ ӱൔ 䪌w୆ॖၛಀ۵ଛᅟଦ໡֥⊷ਘx You Facebook  API Resource

    Owner Client Resource Server Authorization Server
  19. Resource Owner

  20. Resource Owner = User • ࣼ൞୆↌ᅟ֥ User • API ঘ֥֞൞۵

    User ႵἬ֥⊷ਘ • ২ೂݺႶ଀Ẫaྐࡱ⤨ಸ • ൱⃴с⇜ῂႮЧದ⃤ሱ⃷⃾
  21. Resource Owner = Client • ≾⊕౦㣐㢻Ⴕದ֥թᄝb • ২ğ஁܄Ῐ⊷ਘ • Twitter

    Ẁ㬪 App-Only Authorization • Facebook Ẁ㬪 App Access Token
  22. Client

  23. Client • User ൱⃴ἡֻ೘ٚӱൔđ≾ἠӱൔࣼ൞ Client • ২ğFacebook ഈ֥䵔↰a൭Ὠഈ֥ App •

    ܲٚӱൔ္ෘč২ೂ൭Ὠ App aም૫ AppĎ
  24. Client с⇜൙༵䩏⤳ • “Client Registration” • Client ID • Client

    Secret čℶ㬪ૡĎ • Redirect URI ← ≾ἠޓᇗေ
  25. None
  26. Client ID

  27. Client Secret

  28. Redirect URI

  29. Redirect URI • User Чದ⃤ሱ⃷⃾ᆭᗥđْ߭᾵ݔ֞ Client • ေ൙༵ᆷקđ೏҂၂ᇁ≣҂ॖ Redirect Ἶಀ

    • ॖၛᆷק؟⊾đ֌๙ӈ൞၂⊾đࠇ൞Ῐⅽ၂ᇁ • ቋݺ൞ HTTPS č҂ルᇅđ২ೂ൭Ὠ App ࣼḰ҂֞Ď
  30. Redirect URI • https://kktix.com/users/auth/facebook/callback • http://kktix.dev/users/auth/facebook/callback • kktix-app:oauth2/callback

  31. Public v.s. Confidential Client • ۴ῌwି҂ିЌὊ⊷ਘxῲ⃯ٳ • Confidential - Server-Side

    Application • Public - ൭Ὠ App / ም૫ӱൔ / JavaScript App / Browser Extension
  32. Client Authorization (⃾⊈) • ԛൕ Client ID + Secret ཟ

    Auth. Server ⃾⊈ሱ࠭ • ္ࣼ൞䪌 Client ေ֨ೆ֞ Auth. Server • ᆺℳႨ Confidential Client
  33. Client • Ⴕ ID / Secret Ⴈᧄ⃾⊈ • Ⴈ Redirect

    URI ⃷Ќ⏟´ఖ⊨ᆶ֞ᆞ⃷֥ Client • Public / Confidential Ⴕ۲ሱℳႨ֥൱⃴ੀӱ
  34. Endpoints

  35. Endpoints • Authorization Endpoint - Ⴈῲἡ User Чದ⃷⃾൱⃴ • Token

    Endpoint - Ⴈῲ⃸ Client ౼֤ᆇᆞ֥ Token • Redirection Endpoint - Client Ⴈῲ൬⊷ਘႨ
  36. Authorization Endpoint • ἡ User Чದ⃷⃾൱⃴ • ൞၂ἠ↌∉ • ଦ֥֞൞

    “Grant” č൱⃴⊯Ďط҂൞ Token • User ճڭᆭᗥđ὜⊨߭ Client ֥ Redirect URI
  37. Token Endpoint • ἡ Client ౼֤ᆇᆞ֥ Token • JSON API

    Ὠྀ߄ࢸ૫đ↥↌∉
  38. Redirection Endpoint • Ⴈῲạ⏟´ఖࢤ൬ Auth. Server ῲ֥⊷ਘ • Ῐᄝ Client

    ط҂൞ Auth. Server • Client 䩏⤳ℭေ⇔֥ “Callback URL” • Auth. Server ὜⇼⊈ Redirect URI ൞ڎཌྷژҌ⊨ᆶ
  39. SSL! SSL! SSL! • Auth. Server ഈ૫֥ Endpoints с⇜ഈ HTTPS

    • Client с⇜⇼⊈ SSL Certificate ൞ڎކ۬ • Client Redirection Endpoint ҂ルᇅđ֌ିഈቋݺഈ
 ↌ᅟ → ቋݺഈ
 ൭Ὠ / ም૫ App → 㢻Ḱمॖၛ҂ေഈ
  40. Resource Server

  41. Resource Server • Client с⇜ԛൕ Token ҌିΆಀଦ⊷ਘ • Client ᆺေԛൕ

    Token ࣼିΆಀଦ⊷ਘ • ॖၛႨ Scope ཋᇅ Token ିⴺ౼Ⴈ֥⊷ਘữ↏
  42. Resource Server • Password-Free API • Login via YourWebsite™

  43. OAuth 2 Protocol ᄸ喁஝

  44. wᾏẪάđồ Spec άx* *ս䩽҂൞Чದ෮མ֥≾喁ᾏẪ ݠ`ದ

  45. • RFC 6749: The OAuth 2.0 Authorization Framework • 77

    pages (PDF) • RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage • 19 pages (PDF) tl;dr
  46. • Ⴈಀ 3 ἠ‎Ϩ • ⇔ਔ 13 ௉ṁὸ → /me

    ၘồb
  47. OAuth 2.0 Spec(s) • RFC 6749 - ק∕∻ Token ނứႵἬ֥

    Protocol • RFC 6750 - ק∕wBearer Tokenxᄸ喁Ⴈ
  48. RFC 6749: OAuth 2 Protocol • ק∕ਔ OAuth 2 ֥࢘೤a޺ọٚൔ

    • ק∕ਔ⊷ਘႵଧུaᄸ喁஝ • ק∕ਔނứa㍤ứ Token ֥֩ Protocol • ἲ὎ਔ 4 ⊕ӈᾖwℳކ൐Ⴈ OAuth 2 ֥ੀӱx
  49. RFC 6750: Bearer Token • RFC 6749 ᆺἲק൱⃴ٚൔđ㢻ἲק API ᄸ喁Ẳ

    • RFC 6750 ק∕၂⊕ࢡቓ “Bearer” ֥ Token Type • ۲⊕ type Ⴕ҂๝Ẳمđ Bearer ൞ᆰࢤ == ᾋҰ • ၂ओὐࢳℴğwᆰࢤଦῲࣼିႨđ҂Ⴈ⃐ῲ⃐ಀx
  50. Parameters & Data

  51. Client ID / Secret • Ⴈᧄ Client ⃾⊈čClient ֨ೆ֞ Auth.

    ServerĎ • 䩏⤳֥ℭީứἡđ⁙ࣼྛ • HTTP Basic Auth ࠇЇᄝ Form 䥰૫č࣌Ⴈ URLĎ
  52. HTTP Basic Auth ID = abc, Secret = 123 abc:123

    concat with `:` YWJjOjEyMw== base64() Authorization: Basic YWJjOjEyMw== Basic Auth Header
  53. Token(s) • Access Token - յ API Ⴈ֥ • Refresh

    Token - Access Token Ἶ௹ॖၛ㍤ứྍ֥
  54. Access Token • ཟ Resource Server ေ⊷ਘđႨ Access Token •

    ॖၛḳ၂⊾ Scope • ॖၛ℟௹ཋđॖၛӜ⇍ (Revoke) • ൱⃴ੀӱ֥ଢṌࣼ൞ေଦ֞ Access Token
  55. Refresh Token • ㍤ứ Access Token Ⴈđᆺ὜ẖ֞ Auth. Server •

    ḳק၂ἠ Access Tokenđ⅗ Access Token ၂ఏނứ • ႨἾࣼാི
 ྍ֥ Access Token ὜ḳྍ֥ Refresh Token
  56. Scopes • Ⴈῲіൕwॖၛթ౼ଧུ⊷ਘx֥⃴ཋữ↏ • ೂwݺႶ଀Ẫxawཌྷோx • ॖၛ A cover B

    đằಖ Set ൞ቋᾏẪ֥ቓم
  57. Scopes • ണ⃪൱⃴ℭॖၛἲק
 w၂קေἡxࠇw㢻ἡࣼ≁℟ᆴx • Ⴈॢ۬’ఏῲđ২ೂ "friends_list photos" • ֌ޓ؟↌ᅟႨ׹ὂ

    `,` △
  58. State • Ⴈῲٝᆸ CSRF ۾ὧ • Client 㲗 Browser 㲗

    Auth. Server ൞ޓາ↿ˀ • State ẖ֞ Auth. Server ࣼေჰٿ҂ọْ߭ • Client ⇼⊈ᆭ • ⁙ᆴࣼྛđ္ॖၛႨ HMAC ⃐
  59. Protocol: ೂޅ౼֤൱⃴ ạ Client ֥ℶ࢘

  60. ౼֤൱⃴֥ੀӱ 1. Client ཟ Res. Owner ౼֤ “Grant” č൱⃴⊯Ď 2.

    Client Ⴈ “Grant” ཟ Authorization Server ㍤ Token 3. Token ଦ֞ਔđॖၛಀյ API ᆜἠ Protocol ቋₒ֥ᄝ≾䥰
  61. ቋӈᾖ֥ Scenario Ⴕ↌ᅟ Facebook đ୆༐ຬᄝପഈ૫֥ User 
 ἡ୆֥↌ᅟ⃴ཋđॖၛồ౼ପ User ֥⊷ਘ

    Resource Owner Client Token Resource Server ๩Ἶ Facebook ֥ Authorization Server
  62. նࡅ׻ԱἾ ※Ⴈ Library Ա

  63. “Authorization Code Grant Flow”

  64. Auth Code Grant Flow • Grant ൞ऎⅴ֥ሳԱđẀቔ Code • ླေῂἾ

    Browser • ℳႨᧄw↌ᅟx≾⊕ Client
  65. Resource Owner Client ! Authorization Server ※Ӓሱ spec

  66. Resource Owner Browser Client ! Authorization Server ※Ӓሱ spec

  67. Resource Owner Browser Client ! Authorization Server ※Ӓሱ spec Authorization

    Endpoint Token Endpoint Redirection Endpoint
  68. Resource Owner Browser Client ! Authorization Server (A) (A) ID,

    Redirect URI, Scope, State ※Ӓሱ spec Authorization Endpoint Token Endpoint Redirection Endpoint
  69. Resource Owner Browser Client ! Authorization Server (A) (A) ID,

    Redirect URI, Scope, State (B) (B) ↜ Resource Owner ※Ӓሱ spec Authorization Endpoint Token Endpoint Redirection Endpoint
  70. Resource Owner Browser Client ! Authorization Server (A) (A) ID,

    Redirect URI, Scope, State (B) (B) ↜ Resource Owner (C) Grant Code, Scope, State ※Ӓሱ spec Authorization Endpoint Token Endpoint Redirection Endpoint
  71. Resource Owner Browser Client ! Authorization Server (A) (A) ID,

    Redirect URI, Scope, State (B) (B) ↜ Resource Owner (C) Grant Code, Scope, State (D) Grant Code, Client Auth ※Ӓሱ spec Authorization Endpoint Token Endpoint Redirection Endpoint
  72. Resource Owner Browser Client ! Authorization Server (A) (A) ID,

    Redirect URI, Scope, State (B) (B) ↜ Resource Owner (C) Grant Code, Scope, State (D) Grant Code, Client Auth (E) Token ※Ӓሱ spec Authorization Endpoint Token Endpoint Redirection Endpoint
  73. (A) ứԛ൱⃴ണ⃪ Client Ῐ၂ἠ↌ᆶἡ User ề Login with Facebook

  74. (A) ứԛ൱⃴ണ⃪ https://graph.facebook.com/oauth/authorize? response_type=code&client_id=567672586646825& redirect_uri=http%3A%2F%2Flocalhost %3A3000%2Fusers%2Fauth%2Ffacebook %2Fcallback&state=446c63696b24b4b6687cdff62ea bce3a9c9d6333d7c807e6&scope=email (GET Request)

  75. https://graph.facebook.com/oauth/authorize? response_type=code &client_id=567672586646825 &redirect_uri=http://localhost:3000/users/ auth/facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email

  76. https://graph.facebook.com/oauth/authorize? response_type=code &client_id=567672586646825 &redirect_uri=http://localhost:3000/users/ auth/facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email Authorization Endpoint

  77. https://graph.facebook.com/oauth/authorize? response_type=code &client_id=567672586646825 &redirect_uri=http://localhost:3000/users/ auth/facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email іൕ Authorization

    Code Grant Flow Authorization Endpoint
  78. https://graph.facebook.com/oauth/authorize? response_type=code &client_id=567672586646825 &redirect_uri=http://localhost:3000/users/ auth/facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email іൕ Authorization

    Code Grant Flow Client ID Authorization Endpoint
  79. https://graph.facebook.com/oauth/authorize? response_type=code &client_id=567672586646825 &redirect_uri=http://localhost:3000/users/ auth/facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email іൕ Authorization

    Code Grant Flow Client ID Redirect URI Authorization Endpoint
  80. https://graph.facebook.com/oauth/authorize? response_type=code &client_id=567672586646825 &redirect_uri=http://localhost:3000/users/ auth/facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email іൕ Authorization

    Code Grant Flow Client ID Redirect URI Client ֥ State čٝ CSRF Ď Authorization Endpoint
  81. https://graph.facebook.com/oauth/authorize? response_type=code &client_id=567672586646825 &redirect_uri=http://localhost:3000/users/ auth/facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email іൕ Authorization

    Code Grant Flow Client ID Redirect URI Client ֥ State čٝ CSRF Ď མေ⃪౰֥⃴ཋữ↏čScopesĎ Authorization Endpoint
  82. Authorization Server ֥ọቔ 1. ۴ῌ Client ID ᅳ Client 2.

    ⃷⃾ Redirect URI ۵൙༵䩏⤳֥ཌྷژ • ೏҂ᆞ⃷≣ေ₵ấ↪đ҂ॖ⊨߭ἐ URI 3. ⃷⃾མണ⃪֥ scope ᆞ⃷č۬ൔa⤨ಸ֩Ď 4. 㢻↜ⅳࣼ↜ Resource Owner ေ҂ေ൱⃴ (B)
  83. (B) Auth. Server ↜ Res. Owner

  84. Authorization Server ֥ọቔ • ೏ᄍ⇝đ≣⊨߭ Client đڸഈ Grant Code •

    ೏҂ᄍ⇝đ≣⊨߭ Client đ❣ڸഈấ↪⇫༏ • ೏἗἗Ⴕẖ state Ἶῲđ≣ჰٿ҂ọڸഈ
  85. (C) Client ൬֞ Grant Code (GET Request)

  86. HTTP/1.1 302 Found Location: http://localhost:3000/users/auth/ facebook/callback? code=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...)&state=446c636 96b24b4b6687cdff62eabce3a9c9d6333d7c807e6

  87. http://localhost:3000/users/auth/facebook/ callback? code=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...) &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6

  88. http://localhost:3000/users/auth/facebook/ callback? code=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...) &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 Redirection Endpoint

  89. http://localhost:3000/users/auth/facebook/ callback? code=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...) &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 Redirection Endpoint ൱⃴⊯ (Grant

    Code)
  90. http://localhost:3000/users/auth/facebook/ callback? code=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...) &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 Redirection Endpoint ൱⃴⊯ (Grant

    Code) ჰٿ҂ọ֥ State ᆴ
  91. Client ֥ọቔ • ༵ᾋҰ state ۵ session 䥰૫թ֥Ⴕ㢻Ⴕ၂ᇁ • 㢻↜ⅳࣼಀ㍤

    Token ਔ
  92. (D) ଦ Code ㍤ Token • Client ᄝᗥ෻ቓ≾ࡱ൙ • POST

    ֞ Auth. Server ֥ Token Endpoint ㍤ Token • Client Authentication • grant_type=code, code, redirect_uri, client_id (Ᾱ Public Client)
  93. POST /oauth/access_token HTTP/1.1
 Host: graph.facebook.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=authorization_code
 
 &code=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...)
 
 &redirect_uri=http%3A%2F%2Flocalhost %3A3000%2Fusers%2Fauth%2Ffacebook%2Fcallback ※ ൙ℯഈ Facebook Ⴈ GET đ҂ކṌ⊵đ༯ⅾ⃪ሱྛₔṘ
  94. POST /oauth/access_token HTTP/1.1
 Host: graph.facebook.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=authorization_code
 
 &code=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...)
 
 &redirect_uri=http%3A%2F%2Flocalhost %3A3000%2Fusers%2Fauth%2Ffacebook%2Fcallback Token Endpoint ※ ൙ℯഈ Facebook Ⴈ GET đ҂ކṌ⊵đ༯ⅾ⃪ሱྛₔṘ
  95. POST /oauth/access_token HTTP/1.1
 Host: graph.facebook.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=authorization_code
 
 &code=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...)
 
 &redirect_uri=http%3A%2F%2Flocalhost %3A3000%2Fusers%2Fauth%2Ffacebook%2Fcallback Token Endpoint Client Authentication ※ ൙ℯഈ Facebook Ⴈ GET đ҂ކṌ⊵đ༯ⅾ⃪ሱྛₔṘ
  96. POST /oauth/access_token HTTP/1.1
 Host: graph.facebook.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=authorization_code
 
 &code=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...)
 
 &redirect_uri=http%3A%2F%2Flocalhost %3A3000%2Fusers%2Fauth%2Ffacebook%2Fcallback Token Endpoint іൕw໡ଦ֥֞൱⃴⊯൞ Grant Codex Client Authentication ※ ൙ℯഈ Facebook Ⴈ GET đ҂ކṌ⊵đ༯ⅾ⃪ሱྛₔṘ
  97. POST /oauth/access_token HTTP/1.1
 Host: graph.facebook.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=authorization_code
 
 &code=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...)
 
 &redirect_uri=http%3A%2F%2Flocalhost %3A3000%2Fusers%2Fauth%2Ffacebook%2Fcallback Token Endpoint іൕw໡ଦ֥֞൱⃴⊯൞ Grant Codex Grant Code Client Authentication ※ ൙ℯഈ Facebook Ⴈ GET đ҂ކṌ⊵đ༯ⅾ⃪ሱྛₔṘ
  98. POST /oauth/access_token HTTP/1.1
 Host: graph.facebook.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=authorization_code
 
 &code=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...)
 
 &redirect_uri=http%3A%2F%2Flocalhost %3A3000%2Fusers%2Fauth%2Ffacebook%2Fcallback Token Endpoint іൕw໡ଦ֥֞൱⃴⊯൞ Grant Codex Grant Code ჰ Redirect URI Client Authentication ※ ൙ℯഈ Facebook Ⴈ GET đ҂ކṌ⊵đ༯ⅾ⃪ሱྛₔṘ
  99. Authorization Server ֥ọቔ • ⃷⃾ Client Authentication (ID / Secret)

    ᆞ⃷ • ᅳ֞ἐ Grant Code đ⃷⃾ః Redirect URI ၂ଆ၂∄ • 㢻↜ⅳ֥ὐࣼứ Token
  100. (E) ứ Token • Client ֥ Token Request ֥ Response

    • ൞ JSON Response • ॖၛ၂⟸ứ Refresh Token • User ൱⃴֥ Scope ೏∻ണ⃪ℭ҂၂ᇁ≣ေڸഈ
  101. HTTP/1.1 200 OK
 Content-Type: application/json;charset=UTF-8
 Cache-Control: no-store
 Pragma: no-cache
 {


    "access_token":"2YotnFZFEjr1zCsicMWpAA",
 "token_type":"Bearer",
 "expires_in":3600,
 "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
 "scopes":"email"
 }
  102. HTTP/1.1 200 OK
 Content-Type: application/json;charset=UTF-8
 Cache-Control: no-store
 Pragma: no-cache
 {


    "access_token":"2YotnFZFEjr1zCsicMWpAA",
 "token_type":"Bearer",
 "expires_in":3600,
 "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
 "scopes":"email"
 } Access Token
  103. HTTP/1.1 200 OK
 Content-Type: application/json;charset=UTF-8
 Cache-Control: no-store
 Pragma: no-cache
 {


    "access_token":"2YotnFZFEjr1zCsicMWpAA",
 "token_type":"Bearer",
 "expires_in":3600,
 "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
 "scopes":"email"
 } Access Token іൕ≾ἠ Token ൞ Bearer Token
  104. HTTP/1.1 200 OK
 Content-Type: application/json;charset=UTF-8
 Cache-Control: no-store
 Pragma: no-cache
 {


    "access_token":"2YotnFZFEjr1zCsicMWpAA",
 "token_type":"Bearer",
 "expires_in":3600,
 "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
 "scopes":"email"
 } Access Token іൕ≾ἠ Token ൞ Bearer Token 3600 ૰ᆭᗥἾ௹
  105. HTTP/1.1 200 OK
 Content-Type: application/json;charset=UTF-8
 Cache-Control: no-store
 Pragma: no-cache
 {


    "access_token":"2YotnFZFEjr1zCsicMWpAA",
 "token_type":"Bearer",
 "expires_in":3600,
 "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
 "scopes":"email"
 } Access Token іൕ≾ἠ Token ൞ Bearer Token 3600 ૰ᆭᗥἾ௹ Access Token Ớ∣֥ Refresh Token
  106. HTTP/1.1 200 OK
 Content-Type: application/json;charset=UTF-8
 Cache-Control: no-store
 Pragma: no-cache
 {


    "access_token":"2YotnFZFEjr1zCsicMWpAA",
 "token_type":"Bearer",
 "expires_in":3600,
 "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
 "scopes":"email"
 } Access Token іൕ≾ἠ Token ൞ Bearer Token 3600 ૰ᆭᗥἾ௹ Access Token Ớ∣֥ Refresh Token ೏ scope ∻ണ⃪ℭ ҂၂ᇁ≣ေڸഈ
  107. ൭Ὠ App / ም૫ App • ℶ㬪 Public đClient Authentication

    ҂ॖྐ • Token Request ေڸഈ Client ID
 ⃷Ќ Token ứἡᆞ⃷֥ Client • App ⅹܥק URI đೂ
 kktix-app:oauth2-callback
  108. What about JavaScript App • “User-Agent-Based Client” • Public Client

    • Redirect Endpoint ္㢻Ḱمⅹሱị Protocol • Auth. Code Grant Flow ҂ॖႨđᄸ喁ḰĤ
  109. “Implicit Grant Flow”

  110. Implicit Grant Flow • ⊦⁽ἡ Public Client Ⴈ • Grant

    ҂ẖ֞ Client đᆰࢤứ Token • ҂ῂἾ Token Endpoint • ứ֥ Token ๙ӈ൞؋ི௹đࢆ֮Ф๦֥ἀ↿ • ҂ἡ Refresh TokenđἾ௹ᇗྍ஝ണ⃪ੀӱ
  111. Resource Owner Client (JS) ! Authorization Server ※Ӓሱ spec

  112. Resource Owner Browser Client (JS) ! Authorization Server ※Ӓሱ spec

  113. Resource Owner Browser Client (JS) ! Authorization Server ※Ӓሱ spec

    Client’
 (Web Server)
  114. Resource Owner Browser Client (JS) ! Authorization Server ※Ӓሱ spec

    Authorization Endpoint Client’
 (Web Server) Redirection Endpoint
  115. Resource Owner Browser Client (JS) ! Authorization Server (A) (A)

    ID, Redirect URI, Scope, State ※Ӓሱ spec Authorization Endpoint Client’
 (Web Server) Redirection Endpoint
  116. Resource Owner Browser Client (JS) ! Authorization Server (A) (A)

    ID, Redirect URI, Scope, State (B) (B) ↜ Resource Owner ※Ӓሱ spec Authorization Endpoint Client’
 (Web Server) Redirection Endpoint
  117. Resource Owner Browser Client (JS) ! Authorization Server (A) (A)

    ID, Redirect URI, Scope, State (B) (B) ↜ Resource Owner (C) Token (in Frag.), Scope, State ※Ӓሱ spec Authorization Endpoint Client’
 (Web Server) Redirection Endpoint
  118. Resource Owner Browser Client (JS) ! Authorization Server (A) (A)

    ID, Redirect URI, Scope, State (B) (B) ↜ Resource Owner (C) Token (in Frag.), Scope, State ※Ӓሱ spec Authorization Endpoint Client’
 (Web Server) Redirection Endpoint (D) GET Redirect URI (no Token)
  119. Resource Owner Browser Client (JS) ! Authorization Server (A) (A)

    ID, Redirect URI, Scope, State (B) (B) ↜ Resource Owner (C) Token (in Frag.), Scope, State (E) JavaScript (to Decode Token) ※Ӓሱ spec Authorization Endpoint Client’
 (Web Server) Redirection Endpoint (D) GET Redirect URI (no Token)
  120. Resource Owner Browser Client (JS) ! Authorization Server (A) (A)

    ID, Redirect URI, Scope, State (B) (B) ↜ Resource Owner (C) Token (in Frag.), Scope, State (E) JavaScript (to Decode Token) ※Ӓሱ spec Authorization Endpoint Client’
 (Web Server) Redirection Endpoint (D) GET Redirect URI (no Token) (F)
  121. Resource Owner Browser Client (JS) ! Authorization Server (A) (A)

    ID, Redirect URI, Scope, State (B) (B) ↜ Resource Owner (C) Token (in Frag.), Scope, State (E) JavaScript (to Decode Token) ※Ӓሱ spec Authorization Endpoint Client’
 (Web Server) Redirection Endpoint (D) GET Redirect URI (no Token) (G) Assign Access Token (F)
  122. None
  123. (C) ~ (G) ޽ളസଊℿ • (C) Auth. Server ࢡ Browser

    ⊨߭ Redirect URI • https://client.com/oauth2/callback#access_token=… • (D) Browser ὜ಀ GET ἐ URL đ֌҂ݣ # č฿ྟĎ • Token ሱọЌ਽ᄝ Browser ֥ Fragment Part 䥰૫
  124. (C) ~ (G) ޽ളസଊℿ • (E) ᄜ❟߭၂ἠ JavaScript Ⴈῲࢳԛ #

    䥰૫֥ Token • (F) Browser ሱọ run ≾ἠ JavaScript ࢳԛ Token • (G) Ϝࢳԛῲ֥ Token ❟ἡ JavaScript App
  125. ෮ၛ㬪൉喁ླေ Client’ ٳദ • JavaScript ҂ିῘ Redirection Endpoint
 ෮ၛႨ Web

    Server Ῐ • 䥰૫ࣼ൞၂ἠ JavaScript code Ⴈῲࢳԛ Token
 ❣ẖἡ JavaScript App (ᆇ Client)
  126. https://graph.facebook.com/oauth/authorize? response_type=token &client_id=567672586646825 &redirect_uri=http://localhost:3001/jsapp/ facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email

  127. https://graph.facebook.com/oauth/authorize? response_type=token &client_id=567672586646825 &redirect_uri=http://localhost:3001/jsapp/ facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email Authorization Endpoint

  128. https://graph.facebook.com/oauth/authorize? response_type=token &client_id=567672586646825 &redirect_uri=http://localhost:3001/jsapp/ facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email іൕ Implicit

    Grant Flow Authorization Endpoint
  129. https://graph.facebook.com/oauth/authorize? response_type=token &client_id=567672586646825 &redirect_uri=http://localhost:3001/jsapp/ facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email іൕ Implicit

    Grant Flow Client ID Authorization Endpoint
  130. https://graph.facebook.com/oauth/authorize? response_type=token &client_id=567672586646825 &redirect_uri=http://localhost:3001/jsapp/ facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email іൕ Implicit

    Grant Flow Client ID Redirect URI Authorization Endpoint
  131. https://graph.facebook.com/oauth/authorize? response_type=token &client_id=567672586646825 &redirect_uri=http://localhost:3001/jsapp/ facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email іൕ Implicit

    Grant Flow Client ID Redirect URI Client ֥ State čٝ CSRF Ď Authorization Endpoint
  132. https://graph.facebook.com/oauth/authorize? response_type=token &client_id=567672586646825 &redirect_uri=http://localhost:3001/jsapp/ facebook/callback &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &scope=email іൕ Implicit

    Grant Flow Client ID Redirect URI Client ֥ State čٝ CSRF Ď མေ⃪౰֥⃴ཋữ↏čScopesĎ Authorization Endpoint
  133. HTTP/1.1 302 Found Location: http://localhost:3001/jsapp/ facebook/ callback#access_token=AQABIWdeO3miePq0uH2VCUv hGr(...)&state=446c63696b24b4b6687cdff62eabce 3a9c9d6333d7c807e6 &token_type=bearer&expires_in=3600

  134. http://localhost:3000/jsapp/facebook/ callback# token=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...) &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &token_type=Bearer &expires_in=3600

  135. http://localhost:3000/jsapp/facebook/ callback# token=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...) &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &token_type=Bearer &expires_in=3600 Redirection Endpoint

  136. http://localhost:3000/jsapp/facebook/ callback# token=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...) &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &token_type=Bearer &expires_in=3600 Redirection Endpoint

    Access Token
  137. http://localhost:3000/jsapp/facebook/ callback# token=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...) &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &token_type=Bearer &expires_in=3600 Redirection Endpoint

    Access Token ჰٿ҂ọ֥ State ᆴ
  138. http://localhost:3000/jsapp/facebook/ callback# token=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...) &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &token_type=Bearer &expires_in=3600 Redirection Endpoint

    Access Token ჰٿ҂ọ֥ State ᆴ іൕ≾ἠ Token ൞ Bearer Token
  139. http://localhost:3000/jsapp/facebook/ callback# token=AQABIWdeO3miePq0uH2VCUvhGr- voXz3zunrCiX5Bz9IFF8m82bmP(...) &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 &token_type=Bearer &expires_in=3600 Redirection Endpoint

    Access Token ჰٿ҂ọ֥ State ᆴ іൕ≾ἠ Token ൞ Bearer Token 3600 ૰ᆭᗥἾ௹
  140. Redirection Endpoint ֥⤨ಸ <script>
 var access_token = [extract token from

    frag];
 // store token in local storage or cookie
 </script>
  141. Implicit Grant Flow Usage • Facebook JavaScript SDK • ൭Ὠ

    App aም૫ App ္ℳႨ
 Facebook: WebView ᾄⅹܥק Redirect URI
 ሂԛ #access_token
  142. ห⦁ᇿၩ൙⇊ • 㬪ࢆ֮ Token Ф๦ἀ↿đ๙ӈ὜ứ؋ི௹֥ Token • ၹ㬪ॖି⢔ᄯ Token 刈ἡ

    Client đ෮ၛс⇜⇼⊈ᆭ • Facebook: “Token Debug Endpoint”
  143. What if ሱ㸗ሱႨĤ • ሱ࠭⇔֥ script མေႨ Token ಀյ API

    • Server App ၘῂթਔ≷ὂૡđམڿӮ OAuth 2
  144. “Resource Owner Password Credentials Grant Flow”

  145. Resource Owner Client ! Authorization Server ※Ӓሱ spec

  146. Resource Owner Client ! Authorization Server ※Ӓሱ spec Token Endpoint

  147. Resource Owner Client ! Authorization Server ※Ӓሱ spec Token Endpoint

    (A) Username, Password
  148. Resource Owner Client ! Authorization Server (B) Client Auth, Username,

    Password, Scopes ※Ӓሱ spec Token Endpoint (A) Username, Password
  149. Resource Owner Client ! Authorization Server (B) Client Auth, Username,

    Password, Scopes (C) Token ※Ӓሱ spec Token Endpoint (A) Username, Password
  150. Resource Owner Password Credentials Grant Flow • ླေ൞ Resource Owner

    ۚ؇ྐῳ Client • ቔ∊༢ⅼ⤨ࡹ֥∣ႨӱൔčOS X ֥ Twitter ᆜކĎ • ܲٚ∣ႨӱൔčGitHub.appĎ • ౏ః෰⦁֥ੀӱ׻҂ℳႨ
  151. Resource Owner Password Credentials Grant Flow • No “state” ၹ㬪҂ῂἾ

    Browser • No “Redirect URI” ၹ㬪㢻Ⴕ redirection • ᆰࢤ POST ಀ Token Endpoint ଦ Token
  152. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=password
 
 &username=chitsaou
 &password=12345678
 
 &scope=email
  153. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=password
 
 &username=chitsaou
 &password=12345678
 
 &scope=email Token Endpoint
  154. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=password
 
 &username=chitsaou
 &password=12345678
 
 &scope=email Token Endpoint Client Authentication
  155. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=password
 
 &username=chitsaou
 &password=12345678
 
 &scope=email Token Endpoint іൕw໡ଦ֥֞൱⃴⊯൞
 User ֥ Passwordx Client Authentication
  156. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=password
 
 &username=chitsaou
 &password=12345678
 
 &scope=email Token Endpoint іൕw໡ଦ֥֞൱⃴⊯൞
 User ֥ Passwordx Credentials Client Authentication
  157. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=password
 
 &username=chitsaou
 &password=12345678
 
 &scope=email Token Endpoint іൕw໡ଦ֥֞൱⃴⊯൞
 User ֥ Passwordx Credentials Client Authentication མေ⃪౰֥⃴ཋữ↏čScopesĎ
  158. Password ֥↜ⅳ • Token Endpoint ေٝВ৯௥ࢳ • Client ҂ሙϜ≷ૡթఏῲ

  159. What if ҂ླေ UserĤ • ᆺթ౼܄Ῐ⊷ਘ • Data-Mining Twitter Public

    Timeline
  160. “Client Credentials Grant Flow”

  161. Client ! Authorization Server ※Ӓሱ spec

  162. Client ! Authorization Server ※Ӓሱ spec Token Endpoint

  163. Client ! Authorization Server (A) Client Auth, Scopes ※Ӓሱ spec

    Token Endpoint
  164. Client ! Authorization Server (A) Client Auth, Scopes (B) Token

    ※Ӓሱ spec Token Endpoint
  165. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=client_credentials
 
 &scope=search_timeline
  166. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=client_credentials
 
 &scope=search_timeline Token Endpoint
  167. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=client_credentials
 
 &scope=search_timeline Token Endpoint Client Authentication
  168. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=client_credentials
 
 &scope=search_timeline Token Endpoint іൕw໡ Client ေണ⃪ Token ሱႨx Client Authentication
  169. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=client_credentials
 
 &scope=search_timeline Token Endpoint іൕw໡ Client ေണ⃪ Token ሱႨx Client Authentication མေ⃪౰֥⃴ཋữ↏čScopesĎ
  170. 4 built-in grant flows • Authorization Code • Implicit •

    Resource Owner Password Credentials • Client Credentials
  171. ứളấ↪ℭ֥߭∣ٚൔ

  172. Errors on Authorization Endpoint

  173. Errors on Authorization Endpoint 1. ⃾҂ԛ ClientaRedirect URI ҂ژ 2.

    Ṛ⅂ẖấ / Authorization Server 㢻ℯቔଖུۿି 3. Resource Owner ऋ䌉൱⃴ 4. Internal Server Error
  174. Client ⃾҂֤aRedirect URI ҂ژ • Redirect URI 㢻ἡ / ҂ᆞ⃷

    / 㢻൙༵䩏⤳ • ေℶ㬪۾ὧđ҂ॖၛ Redirect ֞ἐ Redirect URI • ေิൕࣞۡ⇫༏ἡ Resource Owner
  175. ః෰ấ↪ • ေ⊨߭ Redirect URI ཟ Client ۡᆩấ↪ • ᄝ

    URI ᗥ૫ڸഈ error parameters • Auth Code Grant Flow - Ⴈ Query ?error=... • Implicit Grant Flow - Ⴈ Fragment #error=...
  176. Error Parameters • error - Error Code đсแđ༯⇈ • error_description

    - ᾏẪ䪌ૼấ↪ • error_uri - ၂ἠ↌ᆶᆷ֞⇈↱䪌ૼ↌∉ • state - ẖ߭ Client ֥ state ჰᆴđᆭభႵἡࣼсแ • ଖུὕ὜ἡ error_subcode čႭఃᇏἽ֥↌ᅟĎ
  177. http://localhost:3000/users/auth/facebook/ callback? error=access_denied
 
 &error_description=User Denies Authrization
 
 &error_uri=https://doc.example.com/...
 


    &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6
  178. http://localhost:3000/users/auth/facebook/ callback? error=access_denied
 
 &error_description=User Denies Authrization
 
 &error_uri=https://doc.example.com/...
 


    &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 Redirection Endpoint
  179. http://localhost:3000/users/auth/facebook/ callback? error=access_denied
 
 &error_description=User Denies Authrization
 
 &error_uri=https://doc.example.com/...
 


    &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 Redirection Endpoint ấ↪
  180. http://localhost:3000/users/auth/facebook/ callback? error=access_denied
 
 &error_description=User Denies Authrization
 
 &error_uri=https://doc.example.com/...
 


    &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 Redirection Endpoint ấ↪ ᾏඍấ↪൞൉喁
  181. http://localhost:3000/users/auth/facebook/ callback? error=access_denied
 
 &error_description=User Denies Authrization
 
 &error_uri=https://doc.example.com/...
 


    &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 Redirection Endpoint ấ↪ ᾏඍấ↪൞൉喁 ु⇈↱䪌ૼ֥ URL
  182. http://localhost:3000/users/auth/facebook/ callback? error=access_denied
 
 &error_description=User Denies Authrization
 
 &error_uri=https://doc.example.com/...
 


    &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 Redirection Endpoint ấ↪ ჰٿ҂ọ֥ State ᆴ ᾏඍấ↪൞൉喁 ु⇈↱䪌ૼ֥ URL
  183. http://localhost:3000/users/auth/facebook/ callback? error=access_denied
 
 &error_description=User Denies Authrization
 
 &error_uri=https://doc.example.com/...
 


    &state=446c63696b24b4b6687cdff62eabce3a9c9d63 33d7c807e6 # Implicit Flow: ㍤Ӯ Fragment Parameter
  184. error = Meaning invalid_request 㢻ἡсေṚ⅂aἡਔ҂ᆞ⃷֥Ṛ⅂a
 ᇗ♶ἡṚ⅂aࠇః෰ჰၹẹᇁ↥مࢳồb unauthorized_client Client ҂ሙႨ≾⊕ Response

    Type
 ῲ౼֤ Authorization Codeb unsupported_response_type Authorization Server ҂ᆦჱ൐Ⴈ≾⊕ Response Typeb invalid_scope ෮ေ౰֥ scope ҂ᆞ⃷a
 ҂ૼa↥مࢳồb Client ᄯӮ֥ấ↪
  185. error = Meaning access_denied Resource Owner ࠇ Authorization Owner
 ऋ䌉൱⃴֥ണ⃪b

    ൱⃴ാḮ
  186. error = Meaning server_error Authorization Server მ֞ၩຓ֥౦㣐ط
 ↥مẕ৘⃪౰b temporarily_unavailable Authorization

    Server ӑ≘ࠇ→ྩᇏđ
 ↥مẕ৘b Authorization Server Internal Server Error
  187. error = Meaning server_error Authorization Server მ֞ၩຓ֥౦㣐ط
 ↥مẕ৘⃪౰b temporarily_unavailable Authorization

    Server ӑ≘ࠇ→ྩᇏđ
 ↥مẕ৘b Q: 㬪൉喁҂ିႨ 500 ߭Ĥ Authorization Server Internal Server Error A: ၹ㬪 500 ҂ᆦჱ Location ⊨ᆶđerror ẖ҂߭ Client
  188. Errors on Token Endpoint

  189. Errors on Token Endpoint 1. Auth. Server ⃾҂֤ Client 2.

    Ṛ⅂ẖấ / Authorization Server 㢻ℯቔଖུۿି 3. ൱⃴⊯ (Grant) ҂ᆞ⃷ 4. Internal Server Error
  190. ߭∣ٚൔ • ၂ੰЇΆ JSON ߭ • ๙ӈ߭ 400 Bad Request

    • ೏ Client ⃾⊈ാḮ & Ⴈ Authorization Header ⃾⊈
 → ೖ WWW-Authenticate header
  191. Error Parameters (≅ Auth E.P.) • error • error_description •

    error_uri • ଖུὕ὜ἡ error_subcode čႭఃᇏἽ֥↌ᅟĎ • No state (ၹ㬪㢻Ⴕ state ẖΆῲά)
  192. HTTP/1.1 401 Unauthorized
 Content-Type: application/json;charset=UTF-8
 WWW-Authenticate: Basic
 Cache-Control: no-store
 Pragma:

    no-cache
 {
 "error":"invalid_client",
 "error_description":"Client Authentication Failed",
 "error_uri":"https://doc.example.com/..."
 }
  193. HTTP/1.1 401 Unauthorized
 Content-Type: application/json;charset=UTF-8
 WWW-Authenticate: Basic
 Cache-Control: no-store
 Pragma:

    no-cache
 {
 "error":"invalid_client",
 "error_description":"Client Authentication Failed",
 "error_uri":"https://doc.example.com/..."
 } ۲Ⴕࡹ∗֥ Response Code
  194. HTTP/1.1 401 Unauthorized
 Content-Type: application/json;charset=UTF-8
 WWW-Authenticate: Basic
 Cache-Control: no-store
 Pragma:

    no-cache
 {
 "error":"invalid_client",
 "error_description":"Client Authentication Failed",
 "error_uri":"https://doc.example.com/..."
 } ۲Ⴕࡹ∗֥ Response Code Client ๩Ἶ Basic Auth
 ⃾⊈ാḮ≣ೖ≾ἠ header
  195. HTTP/1.1 401 Unauthorized
 Content-Type: application/json;charset=UTF-8
 WWW-Authenticate: Basic
 Cache-Control: no-store
 Pragma:

    no-cache
 {
 "error":"invalid_client",
 "error_description":"Client Authentication Failed",
 "error_uri":"https://doc.example.com/..."
 } ۲Ⴕࡹ∗֥ Response Code Client ๩Ἶ Basic Auth
 ⃾⊈ാḮ≣ೖ≾ἠ header ấ↪
  196. HTTP/1.1 401 Unauthorized
 Content-Type: application/json;charset=UTF-8
 WWW-Authenticate: Basic
 Cache-Control: no-store
 Pragma:

    no-cache
 {
 "error":"invalid_client",
 "error_description":"Client Authentication Failed",
 "error_uri":"https://doc.example.com/..."
 } ۲Ⴕࡹ∗֥ Response Code Client ๩Ἶ Basic Auth
 ⃾⊈ാḮ≣ೖ≾ἠ header ấ↪ ᾏඍấ↪൞൉喁
  197. error = Meaning invalid_client Client ⃾⊈ാḮ Authorization Server ⃾҂ԛ Client

    ေ߭ 401 Unauthorized ೂݔ൞Ⴈ Basic Auth ෂԛ Client Auth đ≣ေڸഈ WWW-Authenticate: Basic
  198. error = Meaning invalid_grant ิԛ֥ Grant ࠇ൞ Refresh Token ҂ᆞ⃷a

    Ἶ௹aФӜ⇍đࠇ Redirection URI ҂ژđ ࠇ۴Чࣼ҂൞ἡ୆≾ἠ Clientb ൱⃴⊯҂ᆞ⃷
  199. error = Meaning invalid_request 㢻ἡсေṚ⅂aἡਔ҂ᆞ⃷֥Ṛ⅂a
 ᇗ♶ἡṚ⅂aࠇః෰ჰၹẹᇁ↥مࢳồb unauthorized_client Client ҂ሙႨ≾⊕ Response

    Type
 ῲ౼֤ Authorization Codeb unsupported_grant_type Authorization Server ҂ᆦჱ൐Ⴈ≾⊕
 Grant Typeb invalid_scope ෮ေ౰֥ scope ҂ᆞ⃷a
 ҂ૼa↥مࢳồb Client ᄯӮ֥ấ↪
  200. error = Meaning — — Authorization Server Internal Server Error

  201. error = Meaning — — Q: 㬪൉喁㢻ႵĤ Authorization Server Internal

    Server Error A: ၹ㬪൞ Client ᆰࢤứ Request ֞ Serverđᆰࢤ₵ 500 ࣼྛ
  202. ଦ֞ Token ਔđೂޅյ API RFC 6750 “Bearer Token Usage”

  203. HTTP/1.1 200 OK
 Content-Type: application/json;charset=UTF-8
 Cache-Control: no-store
 Pragma: no-cache
 {


    "access_token":"2YotnFZFEjr1zCsicMWpAA",
 "token_type":"Bearer",
 "expires_in":3600,
 "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
 "scopes":"email"
 }
  204. Bearer Token • RFC 6750 ק∕đ၂⊕ OAuth 2.0 ֥ Token

    • ႨمቋᾏẪğԛൕ Token ἡ Resource Server • Token ⤨ಸ⁙ࣼྛ • Spec ᆺἲקԛൕ Token ֥ٚൔ & ấ↪⇫༏
  205. ԛൕ Token ֥ٚم • (in Header) Authorization: Bearer 2YotnFZF... •

    (in Body) &access_token=2YotnFZF... • (in URL) ?access_token=2YotnFZF... ҂๷ᾑ ቋ๷ᾑ
  206. Authorization: Basic XXXXXXXX • с⇜ᆦჱ • ᆰࢤϜ Token ሳԱ٢Ά Header

    ࣼྛਔ ቋ๷ᾑ GET /me.json HTTP/1.1
 Host: api.example.com
 Authorization: Bearer 2YotnFZF...
  207. in Request Body • ℳႨᧄ "Form" ᆭ ֥ request (POST, PATCH

    etc.) • ҂ॖၛ൞ multi-part • Content-Type: application/x-www-form-urlencoded
  208. POST /api/articles HTTP/1.1
 Host: api.example.com
 Content-Type: application/x-www-form- urlencoded
 
 title=Test%20Article


    &content=%28ry%0A%0D
 &access_token=2YotnFZF...
  209. ҂๷ᾑ in URL Query Param • ҂๷ᾑđၹ㬪ॖି὜Фὸᄝ log 䥰 •

    ေ⃷Ќ response ൞ non-cacheable • Ⴕ Form ିႨࣼ᾽ਈႨ Form Body
  210. GET /api/articles?access_token=2YotnFZF... HTTP/1.1
 Host: api.example.com HTTP/1.1 200 OK
 Content-Type: application/json;charset=UTF-8


    Cache-Control: private (or no-store if not 200)
  211. ứളấ↪ℭ֥߭∣ٚൔ

  212. Bearer Token Error 1. Ṛ⅂ẖấ 2. Token ҂ᆞ⃷ 3. Scope

    ⃴ཋ҂ቀ
  213. ߭∣ٚൔ • ၂ੰႨ WWW-Authenticate header ߭ấ↪ • Ⴕԛൕ Token đҌିڸഈః෰

    Error Parameters • ※ 㢻ἲק҂ିᄜႨ JSON ߭
  214. error = Status Meaning invalid_request 400 㢻ἡсေṚ⅂aἡਔ҂ᆞ⃷֥Ṛ⅂
 ᇗ♶ἡṚ⅂aᇗ♶ԛൕ Access Token


    ࠇః෰ჰၹẹᇁ↥مࢳồb invalid_token 401 Access Token Ἶ௹aФӜ߭a↥مࢳồb Client ॖၛᇗྍണ⃪၂ἠ Token ᄜℷb insufficient_scope 403 Token ֥ scope ⃴ཋ҂ቀb Error ॖၛڸഈ scope= ῲิൕ෮ླ⃴ཋb
  215. HTTP/1.1 401 Unauthorized
 WWW-Authenticate: Bearer realm="The API"
 error="invalid_token"
 error_description="Token is

    not usable." HTTP/1.1 403 Forbidden
 WWW-Authenticate: Bearer realm="The API",
 error="insufficient_scope",
 error_description="Scope not sufficient.",
 scope="friend_list photo"
  216. ປಆ㢻ԛൕ Access Token HTTP/1.1 401 Unauthorized
 WWW-Authenticate: Bearer realm="The API"

    GET /api/articles HTTP/1.1
 Host: api.example.com
  217. Token Ἶ௹ → ㍤ứ Token Refresh

  218. Token Refresh • ଦ Access Token ނứℭ֥ Refresh Token ಀ㍤ứ

    • ჰЧ㢻Ⴕứ Refresh Token đࣼ҂ି㍤ứ • POST ֞ Token Endpoint
  219. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=refresh_token
 
 &refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
 
 &scope=search_timeline
  220. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=refresh_token
 
 &refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
 
 &scope=search_timeline Token Endpoint
  221. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=refresh_token
 
 &refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
 
 &scope=search_timeline Token Endpoint Client Authentication
  222. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=refresh_token
 
 &refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
 
 &scope=search_timeline Token Endpoint іൕw໡ Client ေ㍤ứྍ֥ Tokenx Client Authentication
  223. POST /token HTTP/1.1
 Host: oauth.example.com
 Authorization: Basic YWJjOjEyMw==
 Content-Type: application/x-www-form-

    urlencoded
 
 grant_type=refresh_token
 
 &refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
 
 &scope=search_timeline Token Endpoint іൕw໡ Client ေ㍤ứྍ֥ Tokenx Client Authentication scope ॖസ੻đ҂ॖնᧄ
 Access Token ണ⃪Ἶ֥⃴ཋ
  224. ⚧ᄯ OAuth 2 Provider ֥ٚم

  225. = ᄯ Authorization Server

  226. Service spec ཌྷಸ ᆦჱ֥ Grant Types scope ٳۯ Refresh Token

    Client ⃾⊈ Facebook ✕ Auth Code, Implicit, Client Cred. comma △ (ሱ⚧) GET GitHub ✕ Auth Code, Password (ሱ⚧) comma ✕ POST Twitter ̋ Client Cred. (↥ scope) ✕ Basic Google ✕ Auth Code, Implicit space ̋ POST Microsoft ✕ Auth Code, Implicit ĤĤĤ ̋ POST Dropbox ̋ Auth Code, Implicit (↥ scope) ✕ Basic, POST Amazon ̋ Auth Code, Implicit space ̋ Basic, POST Bitly ✕ Auth Code (϶ሱ⚧), Password (↥ scope) ✕ POST (Auth Code), Basic (Password) ྍশັѰ ✕ Auth Code comma ✕ Basic, GET ׸ϵ ✕ Auth Code, Implicit comma ̋ POST BOX ✕ Auth Code (↥ scope) ̋ POST Basecamp ✕ Auth Code (↥ scope) ̋ POST
  227. ⦁ದᄸ喁ቓ • ҂၂קေᆦჱ෮Ⴕ 4 ⊕ Grant Flow • ҂၂קေႵ Scope

    • ҂၂קေႵ Refresh Token
  228. ⦁ದᄸ喁ቓč҂ݺ֥ٚ૫Ď ✘ ్ Scope ޓ؟ದႨ `,` ✘ Client ⃾⊈҂ᾖ֤׻ᆦჱ HTTP

    Basic Auth ✘ Bearer Token ҂၂ק൞Ⴈ
 “Bearer” Authorization Header
  229. Ⴕ Spec ॖၛ Follow ࣼ Follow ✔ ్ Scope Ⴈॢ۬

    ✔ Client ⃾⊈ᇀഒေᆦჱ Basic Auth ✔ Bearer Token ࣼႨ
 “Bearer” Authorization Header
  230. Step 1: ק∕ Resource Owner

  231. Resource Owner • ࣼק∕Ӯ↌ᅟഈ֥ User ϔ

  232. Step 2: ℟ί Client ܵ৘ࢸ૫

  233. Client Registration (CRUD) • id • secret čℶ㬪ૡĎ • Redirect

    URI ّᆞ҂൞ἡದὸ֥ ෮ၛള⁙ࣼྛ } ← ေ౰ Developer ൙༵ᆷק
  234. Step 3: Ῐ Endpoints

  235. Authorization Endpoint • ๙ӈῘᄝᇶᅟđٚьᆰࢤ⃸ User Ⴈ Cookie ֨ೆ • ⚧ቔ၂ἠ

    Dialog ⃸ User 㢯קေ҂ေᄍ⇝൱⃴ • User ߭ճᆭᗥđRedirect ߭ Client • ὜ Redirect ߭ Client đ෮ၛေ༵⃷Ќ Client ᆞ⃷
  236. Authorization Endpoint halt if !(client_id and redirect_uri matches) error(invalid_scope) if

    !(valid_scope?) error(unsupported_response_type)
 if !(valid_response_type?) # other errors (incomplete pseudo code)
  237. Authorization Endpoint result = ask_user_for_authorization! if result == Authorized then


    if response_type == Code
 callback_params = generate_grant_code()
 else if response_type == Token
 callback_params = generate_token() else if result == Denied then
 callback_params = generate_error_code(access_denied)
  238. Authorization Endpoint if response_type == Code
 redirect_to_client_with_query(callback_params) else if response_type

    == Token
 redirect_to_client_with_fragment(callback_params)
  239. Token Endpoint • ๙ӈῘᄝ API subdomain • ᅶ Spec ቓ

    JSON Response ࣼྛ
  240. Token Endpoint authorize_client! or error(invalid_client) verify_redirect_uri! or error(invalid_request) error(invalid_scope) if

    scope_given and !valid_scope? # other errors token = issue_token(expires_in: 30.days) token_response_by_json(token)
  241. Step 4: Ẳ API

  242. “Resource Server Guard” • Ẳᄝ API ቋຓ૫֥wЌಆx(Guard) • ⇼⊈ૄἠ Request

    ׻с⇜Ⴕᆞ⃷֥ Token
  243. “Resource Server Guard” fetch_token(from: header, form, query) error(401) if !(token_given?)

    error(400) if !(token_decodable?) error(invalid_token) if expired? or revoked? error(insufficient_scope) if scope_sufficient? yield to API
  244. ֻ၂ՑႨ Rails + Grape API ᆜކ OAuth 2 ࣼഈ൭

  245. ֻ၂Ցč੻Ďࣼഈ൭ • Ⴈ Devise ള User (Resource Owner) • Ⴈ

    Doorkeeper ἒ Authorization Server • Ⴈ Grape ἒ API (Resource Server) • ሱ࠭ख़ Resource Server Guard ῲ⅞ API
  246. Why ሱ࠭ख़ Guard • doorkeeper_for ൞ Rails-Only • Rack::OAuth2 ປӮ؇ޓۚđ֌с⇜ሱ࠭ᆜކ

    • Warden::OAuth2 ۵ Devise वᄝ၂ఏ໡҂὜ࢳ • Grape::Middleware::Auth::Oauth2 ۴Ч㢻ቓປ ✔ Best Choice
  247. Source Available on GitHub GitHub.com/chitsaou/oauth2-sample-api

  248. Step 1: ק∕ Resource Owner

  249. ק∕ Resource Owner $ rails g devise:install # ປ

  250. Step 1.5: ᄯ API

  251. ᄯ API class SecretAPI < Grape::API
 namespace "secret"
 format :json


    get "hello" do
 {
 greeting: "Hi,#{current_user.email}"
 }
 end
 end
  252. Step 2: ℟ί Client ܵ৘ࢸ૫

  253. Step 3: Ῐ Endpoints

  254. Step 2 + 3:
 Ῐ Authorization Server

  255. Ῐ Authorization Server $ gem install doorkeeper
 $ rails g

    doorkeeper:install
 $ rails g doorkeeper:migration
 $ rake db:migrate
  256. ℟ק⃾⊈ Resource Owner ֥ٚൔ # ⃾⊈ Resource Owner ֥ٚمđᆰࢤࢤ Devise


    resource_owner_authenticator do
 current_user ||
 warden.authenticate!(:scope => :user)
 end config/initializers/doorkeeper.rb ※ Ӓܲٚ໓ࡱ
  257. New Tables • oauth_application - Clients Registration • oauth_access_grant -

    Stores Auth Grant Codes • oauth_access_token -
 ᆇᆞނứԛಀ֥ Access Tokensđ
 ЇݣỚ∣֥ Refresh Token č≁℟ἬṅĎ
  258. New Routes Action(s) Path Ⴈ๯ new /oauth/authorize Authorization Endpoint create

    /oauth/authorize User ⇝ॖ൱⃴ℭ֥ action destroy /oauth/authorize User ऋ䌉൱⃴ℭ֥ action show /oauth/authorize/:code Local ṦℷႨ update /oauth/authorize Ĥ create /oauth/token Token Endpoint show /oauth/token/info Token Debug Endpoint resources /oauth/applications Clients ܵ৘ࢸ૫ (CRUD) index /oauth/authorized_applications User ܵ৘൱⃴Ἶ֥ Clients destroy /oauth/authorized_applications/:id
  259. Doorkeeper Built-In™ ✔ Authorization Endpoint & Token Endpoint ✔ Token

    Debug Endpoint
 čᄝ Implicit Flow ⇼⊈ Token ֥ᆇℯྟĎ ✔ Client Registration Interface (CRUD) ✔ User ܵ৘൱⃴Ἶ֥ Clients ֥ࢸ૫čॖ RevokeĎ
  260. Let’s Create a Client http://localhost:12345/auth/demo/callback

  261. Let’s Get an Access Token

  262. (A) ứԛ൱⃴ണ⃪ http://localhost:3000/oauth/authorize? client_id=4a407c6a8d3c75e17a5560d0d0e4507c77b 047940db6df882c86aaeac2c788d6 &redirect_uri=http://localhost:12345/auth/ demo/callback &response_type=code

  263. (B) Auth. Server ↜ User

  264. (C) ൱⃴⊯༯ῲਔ http://localhost:12345/auth/demo/callback? code=9e0ad73f94669d9743bb0c2e65c4784f723c11c7 61852477a4d37d0cc9bb914d

  265. (D) ଦ Code ㍤ Token

  266. Token ֞൭ 4ead67fc8917761a7f0cd1f0cae30e905fc93e0d25430 32f58395e5a55b9869e

  267. Step 4: Ẳ API The Most Hard Part

  268. api/concerns/api_guard.rb module APIGuard extend ActiveSupport::Concern end

  269. Building Resource Server Guard • Fetch Access Token via Rack::OAuth2

    • Find Access Token from Model • Validate if Token is not Expired && not Revoked • Validate if Token has Sufficient Scopes • If All Valid, Pass to Grape API
  270. Fetch Access Token via Rack::OAuth2 • use Rack::OAuth2::Server::Resource::Bearer • ൙ℯഈᆺἌ≡Ϝ

    yield ԛῲ֥ Token թᄝଖẕ • ೂݔ Request ҂ầ Token ࣼᆰࢤ Pass ֞༯ἠ stack • ෮ၛ໡ᆺଦ෱ῲ Fetch Token
  271. included do |base|
 # OAuth2 Resource Server Authentication
 use Rack::OAuth2::Server::Resource::Bearer,


    'The API' do |request|
 # Authenticator only fetches the raw token string
 
 # Must yield access token to store it in the env
 request.access_token
 end
 end
  272. def get_token_string
 request.env[Rack::OAuth2::Server::Resource::
 ACCESS_TOKEN]
 end (in helpers block)

  273. Find Access Token Instance • Doorkeeper::AccessToken.authenticate • → #find •

    returns nil if not found
  274. def find_access_token(token_string)
 Doorkeeper::AccessToken.authenticate(token_string)
 end (in helpers block)

  275. Validate the Token • OAuth2::AccessTokenValidationService.validate • ᾋҰႵ㢻Ⴕ Expired a Revoked

    • ॖၛẖ scopes Ṛ⅂ΆಀᾋҰ scope Ⴕ㢻Ⴕ⃆
  276. def validate_access_token(access_token, scopes)
 OAuth2::AccessTokenValidationService
 .validate(access_token, scopes: scopes)
 end (in helpers

    block)
  277. def validate(token, scopes: [])
 if token.expired?
 return EXPIRED
 
 elsif

    token.revoked?
 return REVOKED
 
 elsif !self.sufficent_scope?(token, scopes)
 return INSUFFICIENT_SCOPE
 
 else
 return VALID
 end
 end Token#expired?, Token#revoked?
 ൞ Doorkeeper ⤨ࡹ֥
  278. def sufficent_scope?(token, scopes)
 if scopes.blank?
 # no scope required =>

    any token is valid
 return true
 else
 # scopes required
 #=> Check sufficiently by Set comparison
 required_scopes = Set.new(scopes)
 authorized_scopes = Set.new(token.scopes)
 
 return authorized_scopes >= required_scopes
 end
 end ≾൞ቋᾏẪ֥ࠢކбᾱ ୆ॖၛ၇ླ౰ℯቔဆෘم
  279. ቓ guard! ᄝ Grape 䥰૫Ẳᇾ class SecretAPI < Grape::API
 get

    "hello" do
 guard!
 {
 greeting: "Hi,#{current_user.email}"
 }
 end
 end
  280. def guard!(scopes: [])
 token_string = get_token_string()
 
 if token_string.blank?
 raise

    MissingTokenError
 
 elsif (
 access_token = find_access_token(token_string)
 ).nil?
 raise TokenNotFoundError (in helpers block)
  281. def guard!(scopes: [])
 token_string = get_token_string()
 
 if token_string.blank?
 raise

    MissingTokenError
 
 elsif (
 access_token = find_access_token(token_string)
 ).nil?
 raise TokenNotFoundError ༵ሂԛ Token String (in helpers block)
  282. def guard!(scopes: [])
 token_string = get_token_string()
 
 if token_string.blank?
 raise

    MissingTokenError
 
 elsif (
 access_token = find_access_token(token_string)
 ).nil?
 raise TokenNotFoundError ༵ሂԛ Token String ሂ֥֞൞ॢሳԱđіൕ㢻ἡ Token (in helpers block)
  283. def guard!(scopes: [])
 token_string = get_token_string()
 
 if token_string.blank?
 raise

    MissingTokenError
 
 elsif (
 access_token = find_access_token(token_string)
 ).nil?
 raise TokenNotFoundError ༵ሂԛ Token String ሂ֥֞൞ॢሳԱđіൕ㢻ἡ Token Ⴕἡ֌ᅳ҂֞đ൞ Invalid Token (in helpers block)
  284. else
 case validate_access_token(access_token, scopes)
 when Oauth2::AccessTokenValidationService
 ::INSUFFICIENT_SCOPE
 raise InsufficientScopeError.new(scopes)
 when

    Oauth2::AccessTokenValidationService::EXPIRED
 raise ExpiredError
 when Oauth2::AccessTokenValidationService::REVOKED
 raise RevokedError
 when Oauth2::AccessTokenValidationService::VALID
 @current_user = User.find(access_token
 .resource_owner_id)
 ennnd
  285. else
 case validate_access_token(access_token, scopes)
 when Oauth2::AccessTokenValidationService
 ::INSUFFICIENT_SCOPE
 raise InsufficientScopeError.new(scopes)
 when

    Oauth2::AccessTokenValidationService::EXPIRED
 raise ExpiredError
 when Oauth2::AccessTokenValidationService::REVOKED
 raise RevokedError
 when Oauth2::AccessTokenValidationService::VALID
 @current_user = User.find(access_token
 .resource_owner_id)
 ennnd Scope ҂ژ
  286. else
 case validate_access_token(access_token, scopes)
 when Oauth2::AccessTokenValidationService
 ::INSUFFICIENT_SCOPE
 raise InsufficientScopeError.new(scopes)
 when

    Oauth2::AccessTokenValidationService::EXPIRED
 raise ExpiredError
 when Oauth2::AccessTokenValidationService::REVOKED
 raise RevokedError
 when Oauth2::AccessTokenValidationService::VALID
 @current_user = User.find(access_token
 .resource_owner_id)
 ennnd Scope ҂ژ Ἶ௹ਔ
  287. else
 case validate_access_token(access_token, scopes)
 when Oauth2::AccessTokenValidationService
 ::INSUFFICIENT_SCOPE
 raise InsufficientScopeError.new(scopes)
 when

    Oauth2::AccessTokenValidationService::EXPIRED
 raise ExpiredError
 when Oauth2::AccessTokenValidationService::REVOKED
 raise RevokedError
 when Oauth2::AccessTokenValidationService::VALID
 @current_user = User.find(access_token
 .resource_owner_id)
 ennnd Scope ҂ژ Ἶ௹ਔ Ӝ⇍ਔ
  288. else
 case validate_access_token(access_token, scopes)
 when Oauth2::AccessTokenValidationService
 ::INSUFFICIENT_SCOPE
 raise InsufficientScopeError.new(scopes)
 when

    Oauth2::AccessTokenValidationService::EXPIRED
 raise ExpiredError
 when Oauth2::AccessTokenValidationService::REVOKED
 raise RevokedError
 when Oauth2::AccessTokenValidationService::VALID
 @current_user = User.find(access_token
 .resource_owner_id)
 ennnd Scope ҂ژ Ἶ௹ਔ Ӝ⇍ਔ ׻ OK ࣼ℟ current_user
  289. ቋᗥ൞ Error Response • Rack::OAuth2 䥰૫֥ᆰࢤଦῲႨ • ಌềğinsufficient_scope ҂὜ἡ WWW-Authenticate

    • ၹ㬪ᅶ RFC 2617 ᆺႵ 401 ླေ߭≾ἠ Header
  290. error_classes = [MissingTokenError,
 TokenNotFoundError, ExpiredError,
 RevokedError, InsufficientScopeError]
 
 rescue_from *error_classes,


    oauth2_bearer_token_error_handler (in included block)
  291. def oauth2_bearer_token_error_handler
 Proc.new {|e|
 response = case e
 when MissingTokenError


    Rack::OAuth2::Server::Resource
 ::Bearer::Unauthorized.new
 when TokenNotFoundError
 Rack::OAuth2::Server::Resource
 ::Bearer::Unauthorized.new(
 :invalid_token,"Bad Access Token.")
 # etc. etc.
 end
 response.finish
 }
 end (in ClassMethods module)
  292. guard_all! class SecretAPI < Grape::API
 guard_all!
 get "hello" do
 {


    greeting: "Hi,#{current_user.email}"
 }
 end
 end
  293. module ClassMethods
 def guard_all!(scopes: [])
 before do
 guard! scopes: scopes


    end
 end
 end (in ClassMethods module)
  294. Done­

  295. $ curl -i http://localhost:3000/api/v1/sample/secret
 HTTP/1.1 401 Unauthorized
 WWW-Authenticate: Bearer realm="The

    API"
 Content-Type: application/json
 Cache-Control: no-cache
 {"error":"unauthorized"}
  296. $ curl -i http://localhost:3000/api/v1/sample/secret \
 > -H "Authorization: Bearer XXXXXXXX"


    HTTP/1.1 401 Unauthorized
 WWW-Authenticate: Bearer realm="Protected by OAuth 2.0", error="invalid_token", error_description="Token is expired. You can either do re-authorization or token refresh."
 Content-Type: application/json
 Cache-Control: no-cache
 {"error":"unauthorized"} č⁙แ TokenĎ
  297. $ curl -i http://localhost:3000/api/v1/sample/secret \
 > -H "Authorization: Bearer 4ead67fc8917761a7f0cd1f0cae30e905fc93e0d2543032f58395e

    5a55b9869e"
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {"greeting":"Hi, ducksteven@gmail.com"}
  298. Final Notes • Doorkeeper ≁℟㢻Ⴕ⅞Ῐ Client ֥⃴ཋđ୆ὸ֤ေ⅞ • Doorkeeper ҂ିᆷקᆺῘଧུ

    Flows
 ໡Ῐਔ PR ὕ㢻 merge… • 㢻Ⴕྩ insufficient_scope Error
 ಌ WWW-Authenticate ֥↜ⅳ
  299. What about Omniauth? • github.com/intridea/omniauth-oauth2 • ޓᾏẪđṚ⅂⇔၂⇔ࣼປӮਔ

  300. Conclusion • OAuth 2 Spec ồປҌ὜ᆩ֡෰ᄝἓખ • ồປ Spec →

    ෮Ⴕ API ෮Ⴕ Library ୆׻ु֤׭ • ሱ࠭ᆜކ Grape ބ OAuth 2 ఃℯ㢻Ⴕޓₒ
 ᆺေ׭ Spec ࣼ҂ₒ…
  301. Final Words • ၇ಖࡹ∗୆ಀồ specđၹ㬪໡സ੻ޓ؟↱ᾳ • Ⴍః൞ Security ֥҆ٺ •

    Amazon ֥ OAuth 2 Login ໓ࡱ໡ቋ๷ᾑ
  302. References • RFC 6749 (Spec) tools.ietf.org/html/rfc6749 • RFC 6750 (Spec)

    tools.ietf.org/html/rfc6750 • My Notes: blog.yorkxin.org/tags/OAuth • Many OAuth2-based API Documents
  303. Thank You! Q&A Time