{"id":14831,"date":"2015-12-09T12:00:19","date_gmt":"2015-12-09T03:00:19","guid":{"rendered":"http:\/\/labs.gree.jp\/blog\/?p=14831"},"modified":"2015-12-07T19:09:19","modified_gmt":"2015-12-07T10:09:19","slug":"oauth-for-native-apps","status":"publish","type":"post","link":"https:\/\/labs.gree.jp\/blog\/2015\/12\/14831\/","title":{"rendered":"OAuth for Native Apps"},"content":{"rendered":"<p>GREE Advent Calendar 9\u65e5\u76ee\u306f <a href=\"https:\/\/twitter.com\/nov\">@nov<\/a> \u304c\u62c5\u5f53\u3057\u307e\u3059\u3002<\/p>\n<p>\u50d5\u306f GREE \u3067\u306f\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u90e8\u306b\u6240\u5c5e\u3057\u3066\u304a\u308a\u3001\u793e\u5916\u3067\u306f OAuth \u3084 OpenID Connect \u306a\u3069\u306e Identity \u95a2\u9023\u6280\u8853\u306b\u3064\u3044\u3066\u306e\u7ffb\u8a33\u3084\u8b1b\u6f14\u306a\u3069\u3092\u884c\u3063\u305f\u308a\u3082\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>\u4eca\u65e5\u306f GREE Advent Calendar \u3068\u3044\u3046\u3053\u3068\u3067\u3001Native App \u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3067\u306e OAuth \u306e\u8a71\u3092\u5c11\u3057\u66f8\u3044\u3066\u307f\u3088\u3046\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n<h2>\u306f\u3058\u3081\u306b<\/h2>\n<p>Native App \u3092\u958b\u767a\u3057\u3066\u3044\u308b\u3068\u3001Backend Server \u3068\u306e\u3084\u308a\u3068\u308a\u3084 Facebook Login \u3084 Google Sign-in \u306a\u3069\u3067\u3001\u5fc5\u305a\u3068\u8a00\u3063\u3066\u3044\u3044\u307b\u3069 OAuth 2.0 \u3068\u3044\u3046\u306e\u304c\u51fa\u3066\u304d\u307e\u3059\u3002<\/p>\n<p>OAuth 1.0 \u3068\u7570\u306a\u308a\u30ea\u30af\u30a8\u30b9\u30c8\u306b\u7f72\u540d\u304c\u4e0d\u8981\u3060\u3063\u305f\u308a\u3001Client Secret (a.k.a Consumer Secret) \u7121\u3057\u3067\u3082 Access Token \u304c\u53d6\u5f97\u3067\u304d\u305f\u308a\u3068\u3001\u30b7\u30f3\u30d7\u30eb\u3067 Native App \u3067\u3082\u4f7f\u3044\u3084\u3059\u304f\u306a\u3063\u305f\u3068\u8a00\u308f\u308c\u308b OAuth 2.0 \u3067\u3059\u304c\u3001\u5b9f\u306f\u307e\u3060\u307e\u3060\u5b9f\u88c5\u306b\u4e0d\u5099\u306e\u3042\u308b\u30b1\u30fc\u30b9\u304c\u6563\u898b\u3055\u308c\u307e\u3059\u3002<\/p>\n<p>\u305d\u3053\u3067\u3001\u4ee5\u4e0b\u3067\u306f\u7279\u306b\u5b9f\u88c5\u4e0a\u306e\u554f\u984c\u3092\u591a\u304f\u898b\u304b\u3051\u308b Native App \u3067\u306e OAuth 2.0 \u5229\u7528\u30b1\u30fc\u30b9\u306b\u3064\u3044\u3066\u3001\u826f\u304f\u898b\u304b\u3051\u308b\u30d1\u30bf\u30fc\u30f3\u304b\u3089\u672c\u6765\u3042\u308b\u3079\u304d\u59ff\u3078\u3068\u5c11\u3057\u305a\u3064\u6539\u5584\u3057\u3066\u884c\u304f\u3053\u3068\u306b\u3057\u307e\u3057\u3087\u3046\u3002<\/p>\n<h2>\u60f3\u5b9a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9<\/h2>\n<p>\u307e\u305a\u6700\u521d\u306b\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u30d5\u30ed\u30fc\u3092\u60f3\u5b9a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u3068\u3057\u307e\u3059\u3002<\/p>\n<p><a href=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-15005 size-full\" src=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw.png\" alt=\"Native App w\/o PKCE\" width=\"487\" height=\"489\" srcset=\"https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw.png 487w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw-199x200.png 199w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw-398x400.png 398w\" sizes=\"auto, (max-width: 487px) 100vw, 487px\" \/><\/a><\/p>\n<p>\u3053\u306e\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u3067\u306f\u3001End-User \u306e\u30c7\u30d0\u30a4\u30b9\u4e0a\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u305f Native App \u304c\u540c\u4e00 Developer \u306b\u3088\u308a\u958b\u767a\u30fb\u904b\u55b6\u3055\u308c\u3066\u3044\u308b Backend Server (App Backend) \u3068\u9023\u643a\u3057\u3066\u30b5\u30fc\u30d3\u30b9\u3092\u63d0\u4f9b\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>\u307e\u305f Facebook \u3084 Google \u306a\u3069\u306e\u5916\u90e8 OAuth Server (ID Provider) \u3092\u4f7f\u3063\u305f\u30ed\u30b0\u30a4\u30f3\u306b\u5bfe\u5fdc\u3057\u3001Native App \u306f ID Provider \u304c\u767a\u884c\u3057\u305f Access Token \u3092 App Backend \u306b POST \u3059\u308b\u3053\u3068\u3067\u3001App Backend \u304b\u3089\u8a72\u5f53\u30e6\u30fc\u30b6\u30fc\u5411\u3051\u306e Access Token \u3092\u53d6\u5f97\u3057\u307e\u3059\u3002<\/p>\n<p>\u305d\u306e\u5f8c\u306f\u4ee5\u4e0b3\u3064\u306e\u30d1\u30bf\u30fc\u30f3\u306e API \u30ea\u30af\u30a8\u30b9\u30c8\u304c\u7e70\u308a\u8fd4\u3055\u308c\u3001\u305d\u308c\u305e\u308c\u3067 OAuth 2.0 \u304c\u5229\u7528\u3055\u308c\u308b\u3053\u3068\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<ul>\n<li>Native App \u3068 App Backend<\/li>\n<li>Native App \u3068 ID Provider<\/li>\n<li>App Backend \u3068 ID Provider<\/li>\n<\/ul>\n<p>\u7279\u306b\u660e\u793a\u7684\u306a\u30e6\u30fc\u30b6\u30fc\u767b\u9332\u3092\u5fc5\u8981\u3068\u3057\u306a\u3044\u3053\u3068\u306e\u591a\u3044\u30b2\u30fc\u30e0\u30a2\u30d7\u30ea\u3067\u306f\u5916\u90e8 ID Provider \u3068\u9023\u643a\u3057\u305f\u30e6\u30fc\u30b6\u30fc\u8a8d\u8a3c\u3092\u884c\u3046\u30b1\u30fc\u30b9\u306f\u5c11\u306a\u3044\u3067\u3059\u304c\u3001\u30b2\u30fc\u30e0\u4ee5\u5916\u306e\u30a2\u30d7\u30ea\u3067\u306f\u826f\u304f\u898b\u304b\u3051\u308b\u30d1\u30bf\u30fc\u30f3\u3067\u3059\u306d\u3002<\/p>\n<h2>\u6ce8\u610f\u70b91: Custom URL Scheme \u4e0a\u66f8\u304d\u653b\u6483<\/h2>\n<p>\u4e0a\u8a18\u306e\u3088\u3046\u306a\u30b1\u30fc\u30b9\u3067\u306f\u3001ID Provider \u304b\u3089 Access Token \u3092\u53d7\u3051\u53d6\u308b\u969b\u306b\u3001Custom URL Scheme \u3092\u5229\u7528\u3059\u308b\u3053\u3068\u304c\u591a\u3044\u3067\u3057\u3087\u3046\u3002\u3057\u304b\u3057\u306a\u304c\u3089\u3001\u540c\u3058 Custom URL Scheme \u3092\u8907\u6570\u306e\u30a2\u30d7\u30ea\u304c\u767b\u9332\u53ef\u80fd\u3067\u3042\u308b\u3053\u3068\u304b\u3089\u3001\u8a72\u5f53 Custom Scheme \u7d4c\u7531\u3067\u958b\u304b\u308c\u305f\u30a2\u30d7\u30ea\u304c\u672c\u6765\u671f\u5f85\u3055\u308c\u305f\u30a2\u30d7\u30ea\u3068\u7570\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n<p>\u3053\u306e\u7a74\u3092\u7a81\u304f\u3068\u3001\u4ed6\u306e Native App \u304c\u5229\u7528\u3057\u3066\u3044\u308b Custom URL Scheme \u3092\u4e57\u3063\u53d6\u308b\u653b\u6483\u30a2\u30d7\u30ea\u304c\u6210\u7acb\u3057\u307e\u3059\u3002\u653b\u6483\u8005\u306f\u3001\u305d\u306e\u3088\u3046\u306a\u653b\u6483\u30a2\u30d7\u30ea\u3092\u88ab\u5bb3\u8005\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb &amp; \u30ed\u30b0\u30a4\u30f3\u3055\u305b\u308b\u3053\u3068\u3067\u3001ID Provider \u304a\u3088\u3073 App Backend \u304c\u767a\u884c\u3057\u305f\u88ab\u5bb3\u8005\u30a2\u30ab\u30a6\u30f3\u30c8\u5411\u3051\u306e Access Token \u3084\u3001App Backend \u306b\u4fdd\u5b58\u3055\u308c\u3066\u3044\u308b\u88ab\u5bb3\u8005\u306e\u30c7\u30fc\u30bf\u3078\u306e\u30a2\u30af\u30bb\u30b9\u3092\u5f97\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<h3>\u89e3\u6c7a\u7b561-1: Custom URL Scheme \u306e\u5229\u7528\u3092\u3084\u3081\u308b<\/h3>\n<p>iOS9 \u304a\u3088\u3073 Android M \u4ee5\u4e0a\u3067\u3042\u308c\u3070\u3001\u305d\u308c\u305e\u308c <a href=\"https:\/\/developer.apple.com\/library\/prerelease\/ios\/documentation\/General\/Conceptual\/AppSearch\/UniversalLinks.html\">Universal Links<\/a>\u3001<a href=\"https:\/\/developer.android.com\/training\/app-links\/index.html\">App Links<\/a> \u3068\u3044\u3063\u305f HTTP\/HTTPS \u30ea\u30f3\u30af\u3078\u306e\u30a2\u30af\u30bb\u30b9\u3092\u30c8\u30ea\u30ac\u30fc\u306b\u3057\u3066 OS \u304c\u81ea\u52d5\u7684\u306b\u7279\u5b9a\u30a2\u30d7\u30ea\u3092\u958b\u3044\u3066\u304f\u308c\u308b\u6a5f\u80fd\u304c\u63d0\u4f9b\u3055\u308c\u3066\u3044\u308b\u306e\u3067\u3001\u3053\u3046\u3044\u3063\u305f\u74b0\u5883\u3067\u306f Custom URL Scheme \u3092\u5229\u7528\u305b\u305a\u306b HTTP\/HTTPS \u30ea\u30f3\u30af\u3092\u7528\u3044\u308b\u3053\u3068\u3067\u3001Custom URL Scheme \u4e57\u3063\u53d6\u308a\u653b\u6483\u3092\u9632\u3050\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>\u3053\u306e\u89e3\u6c7a\u7b56\u306f\u975e\u5e38\u306b\u30b7\u30f3\u30d7\u30eb\u3067\u826f\u3044\u306e\u3067\u3059\u304c\u3001iOS9 \u306f\u307e\u3060\u3057\u3082 Android M \u304c\u3072\u308d\u307e\u308b\u306b\u306f\u307e\u3060\u307e\u3060\u6642\u9593\u304c\u304b\u304b\u308a\u305d\u3046\u306a\u306e\u3067\u3001\u3057\u3070\u3089\u304f\u306f\u53e4\u3044 OS \u7528\u306b\u8a72\u5f53 HTTP\/HTTPS URL \u304b\u3089 Custom Scheme \u3092\u958b\u304f Fallback HTML Contents \u3092\u8fd4\u5374\u3059\u308b\u306a\u3069\u306e\u5bfe\u7b56\u304c\u5fc5\u8981\u3067\u3001\u5b8c\u5168\u306b Custom Scheme URL \u306e\u5229\u7528\u3092\u3084\u3081\u308b\u3053\u3068\u306f\u96e3\u3057\u3044\u3067\u3057\u3087\u3046\u3002<\/p>\n<h3>\u89e3\u6c7a\u7b561-2: OAuth PKCE \u62e1\u5f35\u3092\u5229\u7528\u3059\u308b<\/h3>\n<p>\u5b9f\u306f Custom URL Scheme \u306e\u4e57\u3063\u53d6\u308a\u5bfe\u7b56\u3068\u3057\u3066\u3001\u5148\u65e5 (2015\u5e749\u6708) IETF OAuth WG \u3088\u308a <a href=\"https:\/\/tools.ietf.org\/html\/rfc7636\">OAuth PKCE (RFC7636)<\/a> \u3068\u3044\u3046\u62e1\u5f35\u4ed5\u69d8\u304c RFC \u5316\u3055\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>PKCE \u3067\u306f\u3001Authorization Request \u9001\u4fe1\u6bce\u306b Code Verifier \u3068\u547c\u3070\u308c\u308b Secure Random \u3092\u751f\u6210\u3057\u3001\u305d\u306e SHA256 \u30cf\u30c3\u30b7\u30e5\u5024\u3092 Authorization Request \u306b\u6dfb\u4ed8\u3057\u307e\u3059\u3002\u307e\u305f ID Provider \u304b\u3089\u306e\u30ec\u30b9\u30dd\u30f3\u30b9\u3067\u306f\u3001\u76f4\u63a5 Access Token \u3092\u6e21\u3059\u306e\u3067\u306f\u306a\u304f\u3001Authorization Code \u3092\u7d4c\u7531\u3057\u3066 Access Token \u306e\u767a\u884c\u3092\u884c\u3044\u307e\u3059\u3002OAuth PKCE \u3067\u306f\u3001Access Token \u767a\u884c\u6642\u306b\u5143\u306e Code Verifier \u3092 Authorization Code \u3068\u540c\u6642\u306b\u9001\u3089\u305b\u308b\u3053\u3068\u306b\u3088\u308a\u3001\u6700\u521d\u306b Authorization Request \u3092\u30b9\u30bf\u30fc\u30c8\u3057\u305f\u30a2\u30d7\u30ea (\u305d\u306e\u6642\u70b9\u307e\u3067 Code Verifier \u3092\u77e5\u3063\u3066\u3044\u308b\u552f\u4e00\u306e\u30a2\u30d7\u30ea) \u3060\u3051\u304c Access Token \u306e\u767a\u884c\u3092\u884c\u3048\u308b\u3053\u3068\u3092\u4fdd\u8a3c\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>PKCE \u62e1\u5f35\u3092\u63a1\u7528\u3057\u305f\u5834\u5408\u3001\u5f53\u521d\u306e\u30d5\u30ed\u30fc\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002Implicit Flow \u3067\u306f\u306a\u304f\u306a\u308a\u307e\u3057\u305f\u306d\u3002<\/p>\n<p><a href=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-15008 size-full\" src=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw1.png\" alt=\"Native App w\/ PKCE\" width=\"487\" height=\"548\" srcset=\"https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw1.png 487w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw1-178x200.png 178w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw1-355x400.png 355w\" sizes=\"auto, (max-width: 487px) 100vw, 487px\" \/><\/a><\/p>\n<p>Custom URL Scheme \u4e0a\u66f8\u304d\u653b\u6483\u3078\u306e\u5bfe\u7b56\u3068\u3057\u3066\u306f\u3001\u4e0a\u8a182\u3064\u306e\u89e3\u6c7a\u7b56\u3092\u4f75\u7528\u3057\u3001Universal Links &amp; App Links \u3092\u7528\u3044\u305f\u4e0a\u3067\u3001Fallback \u306e Custom URL Scheme \u5229\u7528\u6642\u306b\u3082 PKCE\u3000\u62e1\u5f35\u306b\u3088\u308a\u653b\u6483\u30a2\u30d7\u30ea\u306b ID Provider \u306e Access Token \u304c\u6e21\u3089\u306a\u3044\u3088\u3046\u306b\u3057\u307e\u3057\u3087\u3046\u3002<\/p>\n<p>PKCE \u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u306a\u3044 ID Provider \u3067\u306f\u3001Fallback \u6642\u306e Custom URL Scheme \u4e0a\u66f8\u304d\u653b\u6483\u306b\u5bfe\u3057\u3066\u306f\u5bfe\u51e6\u3057\u304d\u308c\u307e\u305b\u3093\u304c\u3001PKCE \u306f\u300cOAuth Client \u304c PKCE \u5bfe\u5fdc\u3057\u3066\u3044\u306a\u3044 OAuth Server \u306b PKCE \u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u6295\u3052\u305f\u5834\u5408\u3001PKCE \u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u3064\u3051\u3066\u3044\u306a\u3044\u306e\u3068\u540c\u3058\u3088\u3046\u306b\u52d5\u304f (= \u30a8\u30e9\u30fc\u306b\u306f\u306a\u3089\u306a\u3044)\u300d\u3088\u3046\u306b\u8a2d\u8a08\u3055\u308c\u3066\u3044\u308b\u305f\u3081\u3001Native App \u3068\u3057\u3066\u306f\u3068\u308a\u3042\u3048\u305a PKCE \u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u3064\u3051\u3066\u304a\u3044\u3066\u3001ID Provider \u5074\u304c PKCE \u30b5\u30dd\u30fc\u30c8\u3057\u3066\u304f\u308c\u308b\u3088\u3046\u8981\u671b\u3092\u6295\u3052\u308b\u3068\u3044\u3063\u305f\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002<\/p>\n<h2>\u6ce8\u610f\u70b92: Embedded Browser \u306e\u5229\u7528\u306b\u3088\u308b\u30d5\u30a3\u30c3\u30b7\u30f3\u30b0\u30ea\u30b9\u30af\u5897\u5927<\/h2>\n<p>iOS \u3067\u306f Apple \u304c\u5916\u90e8 Safari \u3092\u7acb\u3061\u4e0a\u3052\u308b\u30a2\u30d7\u30ea\u3092\u30ea\u30b8\u30a7\u30af\u30c8\u3057\u3066\u3044\u305f\u3053\u3068\u3082\u3042\u308a\u3001Authorization Request \u9001\u4fe1\u6642\u306b System Browser \u3067\u306f\u306a\u304f Embedded Browser (WebView \u7b49) \u3092\u5229\u7528\u3059\u308b\u30a2\u30d7\u30ea\u304c\u591a\u3044\u3067\u3059\u3002\u3057\u304b\u3057\u306a\u304c\u3089 ID Provider \u5074\u3068\u3057\u3066\u306f\u30013rd-party App \u3067 WebView \u5185\u306b\u30ed\u30b0\u30a4\u30f3\u753b\u9762\u3092\u958b\u304f\u30b1\u30fc\u30b9\u304c\u5897\u3048\u3066\u304f\u308b\u3068\u3001(\u304a\u305d\u3089\u304f\u306f\u3042\u306a\u305f\u306e\u30a2\u30d7\u30ea\u3067\u306f\u306a\u304f\u4ed6\u306e\u60aa\u610f\u3042\u308b\u8ab0\u304b\u306e\u30a2\u30d7\u30ea\u306b\u3088\u308a) \u30d5\u30a3\u30c3\u30b7\u30f3\u30b0\u88ab\u5bb3\u306b\u7e4b\u304c\u308b\u30e6\u30fc\u30b6\u30fc\u304c\u5897\u3048\u308b\u3053\u3068\u304c\u61f8\u5ff5\u3055\u308c\u307e\u3059\u3002<\/p>\n<p>WebView \u306a\u3069\u306e Embedded Browser \u3067\u306f\u3001\u958b\u304b\u308c\u3066\u3044\u308b URL \u3084 SSL \u8a3c\u660e\u66f8\u306e\u78ba\u8a8d\u304c\u3067\u304d\u306a\u304b\u3063\u305f\u308a\u3059\u308b\u305f\u3081\u3001\u30e6\u30fc\u30b6\u30fc\u304c Embedded Browser \u5185\u306e\u30ed\u30b0\u30a4\u30f3\u30d5\u30a9\u30fc\u30e0\u306b\u6163\u308c\u3066\u3057\u307e\u3046\u3068\u3001\u507d\u306e Facebook Login \u30da\u30fc\u30b8\u3092\u958b\u304f\u653b\u6483\u30a2\u30d7\u30ea\u306b\u3088\u3063\u3066\u30d5\u30a3\u30c3\u30b7\u30f3\u30b0\u88ab\u5bb3\u306b\u3042\u3063\u305f\u308a\u3059\u308b\u30b1\u30fc\u30b9\u304c\u5897\u5927\u3057\u307e\u3059\u3002<\/p>\n<h3>\u89e3\u6c7a\u7b56: SFSafariViewController \/ Chrome Custom Tab \u3092\u5229\u7528\u3059\u308b<\/h3>\n<p>iOS9 \u3084 Chrome v45 \u4ee5\u4e0a\u3092\u642d\u8f09\u3057\u305f Android \u3067\u306f\u3001<br \/>\n<a href=\"https:\/\/developer.apple.com\/library\/prerelease\/ios\/documentation\/SafariServices\/Reference\/SFSafariViewController_Ref\/index.html#\/\/apple_ref\/occ\/cl\/SFSafariViewController\">SFSafariViewController<\/a> \u3084 <a href=\"https:\/\/developer.chrome.com\/multidevice\/android\/customtabs\">Chrome Custom Tab<\/a> \u3068\u3044\u3063\u305f\u3001\u30a2\u30d7\u30ea\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3092\u5916\u308c\u308b\u3053\u3068\u306a\u304f System Browser \u76f8\u5f53\u306e User Agent \u304c\u5229\u7528\u53ef\u80fd\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u3089\u306e User Agent \u3067\u306f\u3001URL \u3084 SSL \u8a3c\u660e\u66f8\u306e\u78ba\u8a8d\u304c\u53ef\u80fd\u306a\u3053\u3068\u4ee5\u5916\u306b\u3082\u3001System Browser \u3068\u306e Cookie \u5171\u6709\u306b\u3088\u308a\u30e6\u30fc\u30b6\u30fc\u304c ID Provider \u306b\u30ed\u30b0\u30a4\u30f3\u6e08\u306a\u72b6\u614b\u3067 Authorization Request \u304c\u884c\u3048\u308b\u3053\u3068\u306b\u3088\u308b Login CVR \u5411\u4e0a\u306a\u3069\u306e\u30e1\u30ea\u30c3\u30c8\u3082\u671f\u5f85\u3067\u304d\u308b\u305f\u3081\u3001\u3044\u307e Embedded Browser \u3092\u5229\u7528\u3057\u3066\u3044\u308b\u30a2\u30d7\u30ea\u3082\u3001\u5f90\u3005\u306b SFSafariViewController \/ Chrome Custom Tab \u306b\u79fb\u884c\u3059\u308b\u3053\u3068\u3092\u304a\u52e7\u3081\u3057\u307e\u3059\u3002<\/p>\n<p>\u5f53\u521d\u306e\u30d5\u30ed\u30fc\u306f\u3001\u3053\u308c\u306b\u3088\u308a\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u5909\u308f\u308a\u307e\u3059\u3002\u305f\u3060\u3053\u308c\u306f Native App \u958b\u767a\u8005\u304b\u3089\u3059\u308b\u3068\u3001WebView \u304c SFSafariViewController \u306b\u5909\u308f\u3063\u305f\u3060\u3051\u3067\u3001\u5927\u304d\u306a\u5909\u5316\u3068\u306f\u611f\u3058\u306a\u3044\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u306d\u3002<\/p>\n<p><a href=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-15009 size-full\" src=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw2.png\" alt=\"Native App w\/ PKCE + Browser View\" width=\"677\" height=\"607\" srcset=\"https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw2.png 677w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw2-223x200.png 223w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw2-446x400.png 446w\" sizes=\"auto, (max-width: 677px) 100vw, 677px\" \/><\/a><\/p>\n<p>\u306a\u304a\u3001\u3053\u306e\u554f\u984c\u306b\u3064\u3044\u3066\u306f Google Identity Team \u306e William Dennis \u3092\u4e2d\u5fc3\u306b\u3001IETF OAuth WG \u3067 <a href=\"https:\/\/tools.ietf.org\/id\/draft-wdenniss-oauth-native-apps-00.txt\">OAuth 2.0 for Native Apps<\/a> \u3068\u3044\u3046 Best Practice \u4ed5\u69d8\u304c\u63d0\u6848\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u3053\u306e\u4ed5\u69d8\u66f8\u3067\u306f\u3001\u524d\u8ff0\u306e PKCE \u306b\u3064\u3044\u3066\u3082\u89e6\u308c\u3089\u308c\u3066\u3044\u308b\u306e\u3067\u3001Native App \u3067 OAuth 2.0 \u3092\u5229\u7528\u3059\u308b Developer \u306e\u65b9\u306f\u4e00\u5ea6\u8aad\u3093\u3067\u307f\u308b\u3053\u3068\u3092\u304a\u52e7\u3081\u3057\u307e\u3059\u3002<\/p>\n<p>\u306a\u304a\u3001SFSafariViewController \/ Chrome Custom Tab \u304c\u5229\u7528\u3067\u304d\u306a\u3044\u74b0\u5883\u3067\u306f\u3001\u5916\u90e8 System Browser \u3092\u7acb\u3061\u4e0a\u3052\u308b\u3053\u3068\u306b\u306a\u308b\u3067\u3057\u3087\u3046\u3002\u3053\u306e Fallback \u304c\u5fc5\u8981\u306a\u904e\u6e21\u671f\u3067\u306f\u3001\u3053\u306e\u554f\u984c\u306b\u3088\u308a\u5f15\u304d\u8d77\u3053\u3055\u308c\u308b\u793e\u4f1a\u7684\u554f\u984c\u30681\u30a2\u30d7\u30ea\u5358\u4f53\u306e UX \u3068\u306e\u517c\u306d\u5408\u3044\u3067 WebView \u3092\u63a1\u7528\u305b\u3056\u308b\u3092\u3048\u306a\u3044\u30b1\u30fc\u30b9\u3082\u3042\u308b\u304b\u3068\u306f\u601d\u3044\u307e\u3059\u304c\u3001\u5f90\u3005\u306b SFSafariViewController \/ Chrome Custom Tab \u306e\u63a1\u7528\u304c\u9032\u3080\u3053\u3068\u3092\u671f\u5f85\u3057\u307e\u3059\u3002<\/p>\n<h2>\u6ce8\u610f\u70b93: App Backend \u3078\u306e Token \u7f6e\u63db\u653b\u6483<\/h2>\n<p>\u4e0a\u8a18\u3059\u3079\u3066\u306e\u30d5\u30ed\u30fc\u3067\u3001App Backend \u306f ID Provider \u304c Native App \u5411\u3051\u306b\u767a\u884c\u3057\u305f Access Token \u3092\u53d7\u3051\u53d6\u308a\u3001ID Provider \u304c\u63d0\u4f9b\u3059\u308b Profile API \u304b\u3089\u8a72\u5f53\u30e6\u30fc\u30b6\u30fc\u306e User ID \u3092\u53d6\u5f97\u3057\u3001\u30e6\u30fc\u30b6\u30fc\u3092\u8a8d\u8a3c\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>\u3057\u304b\u3057\u306a\u304c\u3089\u3001Native App \u306e\u4e16\u754c\u3067\u306f\u3001App Backend \u3068\u3044\u3048\u3069\u3082\u300c\u305d\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u9001\u4fe1\u8005\u304c\u6b63\u898f\u306e Native App \u3067\u3042\u308b\u3053\u3068\u300d\u3092\u4fdd\u8a3c\u3059\u308b\u306e\u306f\u975e\u5e38\u306b\u56f0\u96e3\u3067\u3059\u3002\u305d\u306e\u305f\u3081\u3001\u653b\u6483\u8005\u304c\u76f4\u63a5 App Backend \u306b\u30ea\u30af\u30a8\u30b9\u30c8\u3059\u308b\u3053\u3068\u3092\u7981\u6b62\u3059\u308b\u306e\u3082\u3001\u307e\u305f\u56f0\u96e3\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u3053\u306e\u5f31\u70b9\u3092\u7a81\u304d\u3001\u300cID Provider \u306e Profile API \u306b\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b \"\u4ed6\u306e\u30a2\u30d7\u30ea\u5411\u3051\u306e\" Access Token \u3092 App Backend\u306b\u9001\u308a\u3064\u3051\u308b\u653b\u6483\u300d\u304c\u5b58\u5728\u3057\u307e\u3059\u3002<\/p>\n<p>OAuth 2.0 \u306e Access Token \u306f Bearer Token \u3068\u547c\u3070\u308c\u3001\u300cToken \u6240\u6709\u8005\u304c\u8ab0\u3067\u3042\u308d\u3046\u304c\u3001\u305d\u306e Token \u3092\u6301\u3063\u3066\u3044\u308b\u3053\u3068\u306e\u307f\u304c Token \u3092\u5229\u7528\u3059\u308b\u6761\u4ef6\u300d\u3068\u306a\u308a\u307e\u3059\u3002\u3088\u3063\u3066\u3001\u5225\u30a2\u30d7\u30ea\u5411\u3051\u306e Token \u3092\u6e21\u3055\u308c\u305f App Backend \u3082\u3001\u305d\u306e Token \u3092 ID Provider \u306e Profile API \u306b\u9001\u308a\u3064\u3051\u3055\u3048\u3059\u308c\u3070\u3001\u305d\u306e Token \u306b\u7d10\u3065\u304f User ID \u3092\u53d6\u5f97\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u3066\u3057\u307e\u3044\u307e\u3059\u3002\u653b\u6483\u8005\u306e\u904b\u55b6\u3059\u308b\u30b5\u30fc\u30d3\u30b9\u306b\u88ab\u5bb3\u8005\u304c\u4e0e\u3048\u3066\u3057\u307e\u3063\u305f Access Token \u304c App Backend \u306b\u9001\u3089\u308c\u3066\u304d\u305f\u5834\u5408\u3067\u3082\u3001ID Provider \u306e Profile API \u306f\u88ab\u5bb3\u8005\u306e User ID \u3092\u8fd4\u3059\u306e\u3067\u3059\u3002<\/p>\n<p>\u5f53\u7136\u305d\u306e User ID \u3092\u5143\u306b\u30e6\u30fc\u30b6\u30fc\u3092\u8a8d\u8a3c\u3059\u308b\u3068\u3001\u653b\u6483\u8005\u306f\u300c\u3042\u306a\u305f\u304c\u904b\u55b6\u3059\u308b\u30b5\u30fc\u30d3\u30b9\u4e0a\u3067\u3001\u88ab\u5bb3\u8005\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306b\u30ed\u30b0\u30a4\u30f3\u300d\u3067\u304d\u3066\u3057\u307e\u3044\u307e\u3059\u3002\u958b\u767a\u5143\u304c\u3042\u3084\u3057\u3052\u306a\u5360\u3044\u30a2\u30d7\u30ea\u306a\u3069\u306b\u767a\u884c\u3055\u308c\u305f Access Token \u304c\u5927\u91cf\u306b\u5b58\u5728\u3059\u308b\u3053\u3068\u3092\u8003\u3048\u308c\u3070\u3001\u3053\u306e\u653b\u6483\u30d1\u30bf\u30fc\u30f3\u306f\u6c7a\u3057\u3066\u7121\u8996\u3067\u304d\u308b\u3082\u306e\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<\/p>\n<h3>\u89e3\u6c7a\u7b563-1: Token Introspection API \u3092\u5229\u7528\u3059\u308b<\/h3>\n<p>Token \u7f6e\u63db\u653b\u6483\u306f\u3001\u300c\u4ed6\u306e\u30a2\u30d7\u30ea\u306b\u767a\u884c\u3055\u308c\u305f Access Token \u3092\u53d7\u3051\u4ed8\u3051\u306a\u3044\u300d\u3053\u3068\u3067\u5bfe\u7b56\u304c\u53ef\u80fd\u3067\u3059\u3002\u3057\u304b\u3057 OAuth 2.0 \u306e Access Token \u306f\u3001\u57fa\u672c\u7684\u306b\u306f Token \u3092\u898b\u308b\u3060\u3051\u3067\u306f\u3069\u306e\u30a2\u30d7\u30ea\u306b\u767a\u884c\u3055\u308c\u305f\u3082\u306e\u304b\u306f\u4e0d\u660e\u3067\u3059\u3002\u305d\u306e\u305f\u3081\u3001\u5927\u624b ID Provider \u306f\u305d\u306e Token \u304c\u3069\u306e\u30a2\u30d7\u30ea\u5411\u3051\u306b\u767a\u884c\u3055\u308c\u305f\u3082\u306e\u304b\u3092\u8abf\u3079\u308b\u305f\u3081\u306e API \u3092\u63d0\u4f9b\u3057\u3066\u3044\u308b\u3053\u3068\u304c\u591a\u3044\u3067\u3059\u3002<\/p>\n<ul>\n<li><a href=\"https:\/\/developers.facebook.com\/docs\/graph-api\/reference\/v2.5\/debug_token\">Facebook Debug Token API<\/a><\/li>\n<li><a href=\"https:\/\/developers.google.com\/identity\/protocols\/OAuth2UserAgent#validatetoken\">Google Token Info API<\/a><\/li>\n<\/ul>\n<p>\u3053\u3046\u3044\u3063\u305f API \u306e\u3053\u3068\u3092\u3001\"Token Introspection API\" \u3068\u547c\u3073\u307e\u3059\u3002<\/p>\n<p>\u3053\u306e Token Introspection API \u3092\u5229\u7528\u3057\u3001App Backend \u306b\u9001\u3089\u308c\u3066\u304d\u305f Access Token \u304c\u672c\u5f53\u306b App Backend (or Native App) \u5411\u3051\u306b\u767a\u884c\u3055\u308c\u305f\u3082\u306e\u306a\u306e\u304b\u3092\u30c1\u30a7\u30c3\u30af\u3059\u308b\u3053\u3068\u3067\u3001Token \u7f6e\u63db\u653b\u6483\u3092\u9632\u3050\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>Token Introspection \u306e\u30b9\u30c6\u30c3\u30d7\u3092\u8ffd\u52a0\u3059\u308b\u3068\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u30d5\u30ed\u30fc\u306b\u306a\u308a\u307e\u3059\u3002Backend \u3067\u306e API \u30ea\u30af\u30a8\u30b9\u30c8\u304c\u5897\u3048\u307e\u3057\u305f\u306d\u3002<\/p>\n<p><a href=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-15012 size-full\" src=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw3.png\" alt=\"Native App w\/ PKCE + Browser + Token Introspection]\" width=\"677\" height=\"666\" srcset=\"https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw3.png 677w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw3-203x200.png 203w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw3-407x400.png 407w\" sizes=\"auto, (max-width: 677px) 100vw, 677px\" \/><\/a><\/p>\n<p>Token Introspection \u306b\u95a2\u3057\u3066\u306f\u3001OAuth WG \u3067\u5148\u65e5 RFC \u5316\u3055\u308c\u305f <a href=\"https:\/\/tools.ietf.org\/html\/rfc7662\">RFC7662: OAuth 2.0 Token Introspection<\/a> \u3068\u3044\u3046\u4ed5\u69d8\u3082\u53c2\u8003\u306b\u306a\u308b\u3067\u3057\u3087\u3046\u3002(\u5c11\u3057 RFC\u672c\u6765\u306e\u60f3\u5b9a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u304c\u7570\u306a\u308a\u307e\u3059\u304c)<\/p>\n<h3>\u89e3\u6c7a\u7b563-2: Bearer Token \u3092\u5229\u7528\u3057\u305f ID \u9023\u643a\u3092\u3084\u3081\u308b<\/h3>\n<p>Bearer Token \u3068\u306f\u3001\u305d\u3082\u305d\u3082\u767a\u884c\u76f8\u624b (audience) \u304c\u8ab0\u304b\u3092\u6c17\u306b\u305b\u305a\u4f7f\u3046\u3082\u306e\u3067\u3059\u3002\u3057\u304b\u3057\u3001Token \u7f6e\u63db\u653b\u6483\u306e\u4f8b\u3092\u307f\u3066\u3082\u308f\u304b\u308b\u901a\u308a\u3001ID \u9023\u643a\u3092\u884c\u3046\u5834\u5408\u300c\u305d\u306e Token \u304c\u3069\u306e\u30e6\u30fc\u30b6\u30fc\u306b\u7d10\u4ed8\u3044\u3066\u3044\u308b\u304b\u300d\u3068\u540c\u69d8\u306b\u300c\u305d\u306e Token \u304c\u3069\u306e\u30a2\u30d7\u30ea\u306b\u5bfe\u3057\u3066\u767a\u884c\u3055\u308c\u305f\u3082\u306e\u304b\u300d\u3068\u3044\u3046\u306f\u975e\u5e38\u306b\u91cd\u8981\u3067\u3059\u3002<\/p>\n<p>ID \u9023\u643a\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3067\u306f\u3001Token \u306b\u7d10\u4ed8\u3044\u305f\u30e6\u30fc\u30b6\u30fc\u306e\u3053\u3068\u3092 Subject\u3001Token \u767a\u884c\u5bfe\u8c61\u306e Client \u3092 Audience\u3001Token \u767a\u884c\u8005\u3092 Issuer \u3068\u547c\u3073\u3001Token \u691c\u8a3c\u6642\u306b\u306f\u3053\u306e3\u3064\u3092\u30c1\u30a7\u30c3\u30af\u3059\u308b\u5fc5\u8981\u304c\u6709\u308a\u307e\u3059\u3002Token \u7f6e\u63db\u653b\u6483\u306f\u3001Audience \u306e\u30c1\u30a7\u30c3\u30af (Audience Restriction) \u306e\u4e0d\u5099\u3092\u4ed8\u3044\u305f\u653b\u6483\u306e1\u4f8b\u3067\u3059\u3002<\/p>\n<p>\u3059\u3067\u306b OpenID Connect \u306b\u89e6\u308c\u305f\u3053\u3068\u304c\u3042\u308b\u65b9\u306f\u304a\u6c17\u3065\u304d\u3067\u3057\u3087\u3046\u304c\u3001OpenID Connect \u304c OAuth 2.0 \u306b\u8ffd\u52a0\u3057\u3066\u3044\u308b ID Token \u3068\u3044\u3046\u3082\u306e\u306f\u3001Token \u81ea\u4f53\u306b Issuer\u3001Audience\u3001Subject \u3092\u7f72\u540d\u4ed8\u304d\u3067\u542b\u3093\u3067\u3044\u307e\u3059\u3002\u3053\u308c\u306f\u307e\u3055\u3057\u304f Bearer Token \u3092\u7528\u3044\u305f ID \u9023\u643a\u306e\u672c\u8cea\u7684\u554f\u984c\u3092\u89e3\u6c7a\u3059\u308b\u624b\u6bb5\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u6b8b\u5ff5\u306a\u304c\u3089\u3001\u6700\u5927\u306e ID Provider \u3067\u3042\u308b Facebook \u306f OpenID Connect \u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u304c\u3001OpenID Connect \u304c\u5229\u7528\u3067\u304d\u308b Google \u3084 Yahoo! Japan \u306a\u3069\u306e ID Provider \u3068\u9023\u643a\u3059\u308b\u5834\u5408\u306b\u306f\u3001OAuth 2.0 \u5358\u4f53\u3067\u306f\u306a\u304f OpenID Connect \u3092\u5229\u7528\u3059\u308b\u3068\u826f\u3044\u3067\u3057\u3087\u3046\u3002<\/p>\n<p>OpenID Connect \u3092\u5229\u7528\u3059\u308b\u3068\u3001Token Introspection API \u3092\u5229\u7528\u3059\u308b\u4ee3\u308f\u308a\u306b ID Token \u306e\u7f72\u540d\u691c\u8a3c\u3092\u884c\u3048\u3070\u3088\u3044\u3067\u3059\u3002\u30d5\u30ed\u30fc\u3068\u3057\u3066\u306f\u5c11\u3057\u5358\u7d14\u306b\u306a\u308b\u306e\u304c\u304a\u5206\u304b\u308a\u3067\u3057\u3087\u3046\u3002(\u8a73\u3057\u3044 ID Token \u306e\u691c\u8a3c\u65b9\u6cd5\u306b\u3064\u3044\u3066\u306f <a href=\"http:\/\/openid-foundation-japan.github.io\/openid-connect-implicit-1_0.ja.html#IDTokenValidation\">OpenID Connect Implicit Client Implementer's Guide 1.0 (\u7ffb\u8a33\u7248)<\/a> \u306b\u5f93\u3063\u3066\u304f\u3060\u3055\u3044)<\/p>\n<p><a href=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-15013 size-full\" src=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw4.png\" alt=\"Native App w\/ PKCE + Browser + ID Token\" width=\"677\" height=\"597\" srcset=\"https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw4.png 677w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw4-227x200.png 227w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw4-454x400.png 454w\" sizes=\"auto, (max-width: 677px) 100vw, 677px\" \/><\/a><\/p>\n<p>User ID \u81ea\u4f53\u306f ID Token \u306b\u542b\u307e\u308c\u3066\u3044\u308b\u305f\u3081\u3001User ID \u4ee5\u5916\u306e\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u60c5\u5831\u304c\u4e0d\u8981\u306a\u5834\u5408\u306f Profile API \u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u5fc5\u8981\u3059\u3089\u306a\u304f\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u306a\u304a\u3001Token Introspection API \u3082\u63d0\u4f9b\u3057\u3066\u304a\u3089\u305a\u3001OpenID Connect \u3082\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u306a\u3044 OAuth Server \u306f\u3001(\u5c11\u306a\u304f\u3068\u3082 ID Provider \u3068\u3057\u3066\u306f) Native App \u306e\u4e16\u754c\u3067\u306f\u5229\u7528\u3067\u304d\u306a\u3044\u3067\u3057\u3087\u3046\u3002<\/p>\n<h2>\u4e00\u65e6\u307e\u3068\u3081<\/h2>\n<p>\u3044\u304b\u304c\u3067\u3057\u3087\u3046\u3001\u601d\u3063\u305f\u3088\u308a Native App \u3067 OAuth 2.0 \u3092\u5229\u7528\u3059\u308b\u969b\u306b\u6ce8\u610f\u3059\u3079\u304d\u3053\u3068\u304c\u591a\u3044\u306a\u3068\u611f\u3058\u3089\u308c\u305f\u65b9\u304c\u591a\u304b\u3063\u305f\u306e\u3067\u306f\u306a\u3044\u3067\u3057\u3087\u3046\u304b\uff1f<\/p>\n<p>\u4eca\u56de\u53d6\u308a\u4e0a\u3052\u305f\u30b1\u30fc\u30b9\u3067\u306f\u3001\u672c\u6765 OAuth 2.0 \u304c\u60f3\u5b9a\u3057\u3066\u3044\u305f End-User\u3001OAuth Client (Native App)\u3001OAuth Server (ID Provider) \u3068\u3044\u30463\u8005\u4ee5\u5916\u306b App Backend \u3068\u3044\u30464\u8005\u76ee\u304c\u5b58\u5728\u3059\u308b\u305f\u3081\u3001OAuth Core \u306b\u5f93\u3063\u3066\u3044\u308b\u3060\u3051\u3067\u306f Native App \u3068 App Backend \u306e\u9593\u3067\u8106\u5f31\u6027\u304c\u751f\u307e\u308c\u308b\u3053\u3068\u304c\u591a\u3044\u3067\u3059\u3002\u7279\u306b\u6700\u5f8c\u306e Token \u7f6e\u63db\u653b\u6483\u306f\u30012012\u5e74\u304b\u3089\u77e5\u3089\u308c\u3066\u3044\u308b\u554f\u984c\u3067\u3042\u308b\u306b\u3082\u304b\u304b\u308f\u3089\u305a\u3001\u3044\u307e\u3067\u3082 Facebook Login \u3092\u63a1\u7528\u3057\u3066\u3044\u308b Native App \u306b\u975e\u5e38\u306b\u591a\u304f\u898b\u53d7\u3051\u3089\u308c\u308b\u30d1\u30bf\u30fc\u30f3\u3067\u3059\u306e\u3067\u3001\u3082\u3057\u307f\u306a\u3055\u3093\u306e\u4f1a\u793e\u3067\u305d\u306e\u3088\u3046\u306a\u30a2\u30d7\u30ea\u304c\u3042\u308b\u5834\u5408\u306b\u306f\u3001\u4e00\u5ea6\u5b9f\u88c5\u3092\u30c1\u30a7\u30c3\u30af\u3057\u3066\u307f\u308b\u3053\u3068\u3092\u304a\u52e7\u3081\u3057\u307e\u3059\u3002<\/p>\n<h2>\u6700\u5f8c\u306b\u3001\u8fd1\u3044\u672a\u6765\u306e\u8a71\u3092\u3082\u3046\u5c11\u3057<\/h2>\n<p>\u4eca\u56de\u306e\u60f3\u5b9a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u3067\u3042\u3063\u305f Native App x App Backend \u3068\u3044\u3046\u30b1\u30fc\u30b9\u306f\u3001IETF OAuth WG \u3084 OpenID Connect \u306e\u4ed5\u69d8\u7b56\u5b9a\u3092\u884c\u3063\u3066\u3044\u308b OpenID Foundation \u3067\u3082\u975e\u5e38\u306b\u6ce8\u76ee\u5ea6\u306e\u9ad8\u3044\u30bf\u30fc\u30b2\u30c3\u30c8\u3067\u3059\u3002<\/p>\n<p>\u4eca\u56de\u306f\u8a73\u3057\u304f\u306f\u89e6\u308c\u307e\u305b\u3093\u304c\u3001\u73fe\u72b6\u306e OAuth \u4ed5\u69d8\u3067\u306f\u3001\u4e0a\u8a18\u3067\u6319\u3052\u305f\u554f\u984c\u306b\u5bfe\u5fdc\u3057\u3064\u3064\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u8981\u671b\u3092\u5168\u3066\u6e80\u305f\u305b\u308b\u3088\u3046\u306a\u30bb\u30ad\u30e5\u30a2\u306a\u4ed5\u69d8\u306f\u7b56\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002<\/p>\n<ul>\n<li>App Backend &lt;-&gt; ID Provider \u9593\u3067\u306f Client \u8a8d\u8a3c\u3092\u884c\u3044\u305f\u3044<\/li>\n<li>Client \u8a8d\u8a3c\u306a\u3057\u3067 Access Token \u3092\u53d6\u308c\u308b Native App \u3068 Client \u8a8d\u8a3c\u5fc5\u9808\u306e App Backend \u3067\u306f Access Token \u306e Scope \u3084\u6709\u52b9\u671f\u9650\u306b\u5dee\u3092\u3064\u3051\u305f\u3044<\/li>\n<li>Native App and\/or App Backend \u3067\u6709\u52b9\u671f\u9650\u306e\u9577\u3044 Token (Refresh Token) \u304c\u6b32\u3057\u3044<\/li>\n<\/ul>\n<p>\u3044\u307e\u73fe\u5728\u306f\u3001OAuth WG \u3068 OpenID Foundation \u3067\u7b56\u5b9a\u3055\u308c\u3066\u3044\u308b\u5404\u7a2e\u62e1\u5f35\u4ed5\u69d8\u3092\u898b\u3066\u3044\u308b\u3068\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u65b9\u5411\u6027\u306b\u9032\u3093\u3067\u3044\u308b\u3088\u3046\u3067\u3059\u3002<\/p>\n<ul>\n<li>Client \u8a8d\u8a3c\u306a\u3057\u3067\u3082 Native App \u306b\u306f Refresh Token \u3092\u767a\u884c\u3059\u308b\n<ul>\n<li>\u3053\u308c\u306f\u4eca\u3067\u3082\u53ef<\/li>\n<li>Refresh Token \u767a\u884c\u306b\u306f PKCE \u5fc5\u9808\u3068\u3057\u3066\u3082\u826f\u3044\u3067\u3057\u3087\u3046<\/li>\n<\/ul>\n<\/li>\n<li>Native App -&gt; App Backend \u306b\u306f ID Token \u3092\u9001\u4fe1\u3059\u308b\n<ul>\n<li>\u8a72\u5f53 ID Token \u306f PKCE Verifier \u3068\u7d10\u3065\u3051\u3089\u308c\u3066\u3044\u308b ([ACDC Extension](https:\/\/bitbucket.org\/openid\/napps\/src\/c22a2adb3f66f7a34fb599285720498782390f7d\/draft-acdc-01.txt?at=default&amp;fileviewer=file-view-default) \u53c2\u7167)<\/li>\n<\/ul>\n<\/li>\n<li>Refresh Token \u3092\u767a\u884c\u3059\u308b\u305f\u3081 App Backend \u3067\u3082 Token Endpoint \u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\n<ul>\n<li>ID Token \u3068 Access Token \u306e\u4ea4\u63db\u306b\u306f [Token Exchange](https:\/\/tools.ietf.org\/html\/draft-ietf-oauth-token-exchange) \u3092\u5229\u7528<\/li>\n<li>Onetime-only &amp; Client \u8a8d\u8a3c\u5fc5\u9808\u306b\u306a\u308b\u3067\u3057\u3087\u3046<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><a href=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw5.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-15014 size-full\" src=\"http:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw5.png\" alt=\"Native App w\/ Backend (future)\" width=\"705\" height=\"607\" srcset=\"https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw5.png 705w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw5-232x200.png 232w, https:\/\/labs.gree.jp\/blog\/wp-content\/uploads\/2015\/12\/cdraw5-465x400.png 465w\" sizes=\"auto, (max-width: 705px) 100vw, 705px\" \/><\/a><\/p>\n<p>\u3053\u306e\u3088\u3046\u306a\u30b1\u30fc\u30b9\u306b\u3064\u3044\u3066\u3082\u3001\u3044\u3064\u304b\u3069\u3053\u304b\u3067\u8b70\u8ad6\u3067\u304d\u308b\u5834\u6240\u3092\u7528\u610f\u3057\u305f\u3044\u306a\u3068\u601d\u3044\u307e\u3059\u3002\u4f8b\u3048\u3070 <a href=\"http:\/\/idcon.org\">#idcon<\/a> \u3068\u304b\u3002<\/p>\n<p>\u3067\u306f\u3001\u660e\u65e5\u306e Liang \u3055\u3093\u306e\u8a18\u4e8b\u3082\u304a\u697d\u3057\u307f\u306b\uff01<\/p>\n<h2>References<\/h2>\n<ul>\n<li><a href=\"http:\/\/openid-foundation-japan.github.io\/rfc6749.ja.html\">RFC6749: The OAuth 2.0 Authorization Protocol (\u7ffb\u8a33\u7248)<\/a><\/li>\n<li><a href=\"http:\/\/openid-foundation-japan.github.io\/rfc6750.ja.html\">RFC6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage (\u7ffb\u8a33\u7248)<\/a><\/li>\n<li><a href=\"http:\/\/openid-foundation-japan.github.io\/rfc6819.ja.html\">RFC6819: OAuth 2.0 Threat Model and Security Considerations (\u7ffb\u8a33\u7248)<\/a><\/li>\n<li><a href=\"http:\/\/openid-foundation-japan.github.io\/openid-connect-implicit-1_0.ja.html#IDTokenValidation\">OpenID Connect Implicit Client Implementer's Guide 1.0 (\u7ffb\u8a33\u7248)<\/a><\/li>\n<li><a href=\"https:\/\/tools.ietf.org\/html\/rfc7636\">RFC7636: Proof Key for Code Exchange by OAuth Public Clients<\/a><\/li>\n<li><a href=\"https:\/\/tools.ietf.org\/html\/rfc7662\">RFC7662: OAuth 2.0 Token Introspection<\/a><\/li>\n<li><a href=\"https:\/\/tools.ietf.org\/html\/draft-ietf-oauth-token-exchange\">OAuth 2.0 Token Exchange<\/a><\/li>\n<li><a href=\"https:\/\/bitbucket.org\/openid\/napps\/src\/c22a2adb3f66f7a34fb599285720498782390f7d\/draft-acdc-01.txt?at=default&amp;fileviewer=file-view-default\">Authorization Cross Domain Code 1.0<\/a><\/li>\n<li><a href=\"https:\/\/developer.apple.com\/library\/prerelease\/ios\/documentation\/General\/Conceptual\/AppSearch\/UniversalLinks.html\">Universal Links (iOS)<\/a><\/li>\n<li><a href=\"https:\/\/developer.android.com\/training\/app-links\/index.html\">App Links (Android)<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>GREE Advent Calendar 9\u65e5\u76ee\u306f @nov \u304c\u62c5\u5f53\u3057\u307e\u3059\u3002 \u50d5\u306f GREE \u3067\u306f\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u90e8\u306b\u6240\u5c5e\u3057\u3066\u304a\u308a\u3001\u793e\u5916\u3067\u306f OAuth \u3084 OpenID Connect \u306a\u3069\u306e Identity \u95a2\u9023\u6280\u8853\u306b [&hellip;]<\/p>\n","protected":false},"author":149,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[],"tags":[54],"class_list":["post-14831","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-advent-calendar"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/posts\/14831","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/users\/149"}],"replies":[{"embeddable":true,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/comments?post=14831"}],"version-history":[{"count":3,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/posts\/14831\/revisions"}],"predecessor-version":[{"id":15020,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/posts\/14831\/revisions\/15020"}],"wp:attachment":[{"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/media?parent=14831"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/categories?post=14831"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/labs.gree.jp\/blog\/wp-json\/wp\/v2\/tags?post=14831"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}