{"id":1509,"date":"2019-05-23T10:11:12","date_gmt":"2019-05-23T01:11:12","guid":{"rendered":"http:\/\/idealive.jp\/blog\/?p=1509"},"modified":"2019-05-23T10:11:12","modified_gmt":"2019-05-23T01:11:12","slug":"laravel%e3%81%a7%e8%aa%8d%e8%a8%bc%e3%81%8c%e5%bf%85%e8%a6%81%e3%81%aaapi%e3%82%92%e3%81%94%e3%81%ab%e3%82%87%e3%81%94%e3%81%ab%e3%82%87","status":"publish","type":"post","link":"https:\/\/idealive.jp\/blog\/2019\/05\/23\/laravel%e3%81%a7%e8%aa%8d%e8%a8%bc%e3%81%8c%e5%bf%85%e8%a6%81%e3%81%aaapi%e3%82%92%e3%81%94%e3%81%ab%e3%82%87%e3%81%94%e3%81%ab%e3%82%87\/","title":{"rendered":"Laravel\u3067\u8a8d\u8a3c\u304c\u5fc5\u8981\u306aAPI\u3092\u3054\u306b\u3087\u3054\u306b\u3087"},"content":{"rendered":"<p>\u3069\u3046\u3082\u3053\u3093\u306b\u3061\u306f\u3002<br \/>\nLaravel\u3070\u3063\u304b\u308a\u3067\u3059\u3002<\/p>\n<p>\u4eca\u56de\u306f\u3001API\u8a8d\u8a3c\u3067\u3059\u3002<br \/>\nLaravel 5.8\u304b\u3089\u3001API\u8a8d\u8a3c\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u304cPassport\u3092\u4f7f\u308f\u306a\u3044\u65b9\u6cd5\u306b\u306a\u3063\u3066\u307e\u3059\u3002<br \/>\n\u3061\u3087\u3063\u3068\u304a\u8a66\u3057\u3067\u3059\u3002<\/p>\n<p>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8 \u21d2\u3000<a href=\"https:\/\/readouble.com\/laravel\/5.8\/ja\/api-authentication.html\" target=\"_blank\" rel=\"noopener\">API\u8a8d\u8a3c 5.8 Laravel<\/a><\/p>\n<hr \/>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">\u76ee\u6b21<\/p>\n<span class=\"ez-toc-title-toggle\"><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/idealive.jp\/blog\/2019\/05\/23\/laravel%e3%81%a7%e8%aa%8d%e8%a8%bc%e3%81%8c%e5%bf%85%e8%a6%81%e3%81%aaapi%e3%82%92%e3%81%94%e3%81%ab%e3%82%87%e3%81%94%e3%81%ab%e3%82%87\/#Migration\" >Migration<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/idealive.jp\/blog\/2019\/05\/23\/laravel%e3%81%a7%e8%aa%8d%e8%a8%bc%e3%81%8c%e5%bf%85%e8%a6%81%e3%81%aaapi%e3%82%92%e3%81%94%e3%81%ab%e3%82%87%e3%81%94%e3%81%ab%e3%82%87\/#%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%AE%E8%A8%AD%E5%AE%9A\" >\u30c8\u30fc\u30af\u30f3\u306e\u8a2d\u5b9a<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/idealive.jp\/blog\/2019\/05\/23\/laravel%e3%81%a7%e8%aa%8d%e8%a8%bc%e3%81%8c%e5%bf%85%e8%a6%81%e3%81%aaapi%e3%82%92%e3%81%94%e3%81%ab%e3%82%87%e3%81%94%e3%81%ab%e3%82%87\/#API%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0\" >API\u306e\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/idealive.jp\/blog\/2019\/05\/23\/laravel%e3%81%a7%e8%aa%8d%e8%a8%bc%e3%81%8c%e5%bf%85%e8%a6%81%e3%81%aaapi%e3%82%92%e3%81%94%e3%81%ab%e3%82%87%e3%81%94%e3%81%ab%e3%82%87\/#javascript\" >javascript<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/idealive.jp\/blog\/2019\/05\/23\/laravel%e3%81%a7%e8%aa%8d%e8%a8%bc%e3%81%8c%e5%bf%85%e8%a6%81%e3%81%aaapi%e3%82%92%e3%81%94%e3%81%ab%e3%82%87%e3%81%94%e3%81%ab%e3%82%87\/#%E6%9C%80%E5%BE%8C%E3%81%AB\" >\u6700\u5f8c\u306b<\/a><\/li><\/ul><\/nav><\/div>\n<h5><span class=\"ez-toc-section\" id=\"Migration\"><\/span>Migration<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>\u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306e\u3068\u304a\u308a\u306b\u3084\u308a\u307e\u3059\u3002<br \/>\n\u25a0\u30b3\u30de\u30f3\u30c9<br \/>\n<code>php artisan make:migration prepare_users_table_for_api_token --table users<\/code><\/p>\n<p>\u4f5c\u6210\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u3092\u7de8\u96c6\u3067\u3059\u3002<\/p>\n<pre class=\"lang:default decode:true \">&lt;?php\r\n\r\nuse Illuminate\\Support\\Facades\\Schema;\r\nuse Illuminate\\Database\\Schema\\Blueprint;\r\nuse Illuminate\\Database\\Migrations\\Migration;\r\n\r\nclass PrepareUsersTableForApiToken extends Migration\r\n{\r\n    \/**\r\n     * Run the migrations.\r\n     *\r\n     * @return void\r\n     *\/\r\n    public function up()\r\n    {\r\n        Schema::table('users', function (Blueprint $table) {\r\n            $table-&gt;string('api_token', 80)-&gt;after('password')\r\n                -&gt;unique()\r\n                -&gt;nullable()\r\n                -&gt;default(null)-&gt;comment('API \u30c8\u30fc\u30af\u30f3');\r\n        });\r\n    }\r\n\r\n    \/**\r\n     * Reverse the migrations.\r\n     *\r\n     * @return void\r\n     *\/\r\n    public function down()\r\n    {\r\n        Schema::table('users', function (Blueprint $table) {\r\n            $table-&gt;dropColumn('api_token');\r\n        });\r\n    }\r\n}\r\n<\/pre>\n<p>\u3042\u3068\u306fmigrate\u3002<\/p>\n<p><code>php artisan migrate<\/code><\/p>\n<p>\u3053\u3053\u307e\u3067\u3067\u6e96\u5099\u5b8c\u4e86\u3067\u3059\u3002<\/p>\n<hr \/>\n<h5><span class=\"ez-toc-section\" id=\"%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%AE%E8%A8%AD%E5%AE%9A\"><\/span>\u30c8\u30fc\u30af\u30f3\u306e\u8a2d\u5b9a<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>\u4eca\u56de\u3001\u753b\u9762\u304b\u3089\u8981\u8a8d\u8a3c\u306aAPI\u3092\u4f7f\u3044\u305f\u3044\u306e\u3067\u3001\u30c8\u30fc\u30af\u30f3\u767a\u884c\u5f8cCookie\u306b\u4ed5\u8fbc\u307f\u305f\u3044\u3068\u601d\u3044\u307e\u3059\u3002<br \/>\n\u3068\u308a\u3042\u3048\u305a\u3001\u753b\u9762\u30a2\u30af\u30bb\u30b9\u306e\u305f\u3073\u306bCookie\u306e\u6709\u7121\u3092\u78ba\u8a8d\u3057\u3001\u306a\u3051\u308c\u3070\u767a\u884c\u3059\u308b\u3001<br \/>\n\u3068\u3044\u3046\u3088\u3046\u306a\u4ed5\u639b\u3051\u306b\u3057\u3088\u3046\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n<p>\u25a0middleware<br \/>\n<code>php artisan make:middleware GenerateApiToken<\/code><\/p>\n<p>\u4f5c\u6210\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u3092\u7de8\u96c6\u3067\u3059\u3002<br \/>\n\u30e9\u30f3\u30c0\u30e0\u306a\u6587\u5b57\u5217\u3092\u4f5c\u3063\u3066\u3001User\u30e2\u30c7\u30eb\u66f4\u65b0\u3068\u540c\u6642\u306bCookie\u306b\u4fdd\u5b58\u3057\u307e\u3059\u3002<br \/>\nCookie\u306e\u4f5c\u308a\u65b9\u306f\u3001CSRF\u30c8\u30fc\u30af\u30f3\u3092\u4f5c\u3063\u3066\u3044\u308b\u3042\u305f\u308a\u3092\u53c2\u8003\u306b\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"lang:default decode:true \">&lt;?php\r\n\r\nnamespace App\\Http\\Middleware;\r\n\r\nuse Carbon\\Carbon;\r\nuse Closure;\r\nuse Illuminate\\Support\\Facades\\Auth;\r\nuse Illuminate\\Support\\Str;\r\nuse Symfony\\Component\\HttpFoundation\\Cookie;\r\n\r\nclass GenerateApiToken\r\n{\r\n    \/**\r\n     * Handle an incoming request.\r\n     *\r\n     * @param  \\Illuminate\\Http\\Request  $request\r\n     * @param  \\Closure  $next\r\n     * @return mixed\r\n     *\/\r\n    public function handle($request, Closure $next)\r\n    {\r\n        $response = $next($request);\r\n\r\n        $user = Auth::user();\r\n        if ($user) {\r\n            if (!$request-&gt;cookie('api_token')) {\r\n                $apiToken = Str::random(60);\r\n                $user-&gt;update(['api_token' =&gt; $apiToken]);\r\n                $response-&gt;headers-&gt;setCookie(\r\n                    new Cookie('api_token',\r\n                        $apiToken,\r\n                        Carbon::now()-&gt;addRealMinutes(config('session.lifetime'))-&gt;getTimestamp(),\r\n                        config('session.path'),\r\n                        config('session.domain'),\r\n                        config('session.secure'),\r\n                        false,\r\n                        false,\r\n                        config('session.same_site') ?? null\r\n                    ));\r\n            }\r\n        }\r\n\r\n        return $response;\r\n    }\r\n}\r\n<\/pre>\n<p>app\\Http\\Kernel.php\u306b\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"lang:default decode:true \">        'web' =&gt; [\r\n            \\App\\Http\\Middleware\\EncryptCookies::class,\r\n            \\Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse::class,\r\n            \\Illuminate\\Session\\Middleware\\StartSession::class,\r\n            \/\/ \\Illuminate\\Session\\Middleware\\AuthenticateSession::class,\r\n            \\Illuminate\\View\\Middleware\\ShareErrorsFromSession::class,\r\n            \\App\\Http\\Middleware\\VerifyCsrfToken::class,\r\n            \\Illuminate\\Routing\\Middleware\\SubstituteBindings::class,\r\n            GenerateApiToken::class, \/\/ &lt;- \u8ffd\u52a0\r\n        ],\r\n<\/pre>\n<p>\u3042\u3068\u3001Cookie\u306e\u6697\u53f7\u5316\u306e\u5bfe\u8c61\u304b\u3089\u5916\u3057\u307e\u3059\u3002<br \/>\n\u3053\u308c\u3001\u3084\u3089\u306a\u3044\u3068\u52d5\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u672c\u5f53\u306f\u30c8\u30fc\u30af\u30f3\u3092\u30cf\u30c3\u30b7\u30e5\u5316\u3057\u305f\u308a<br \/>\n\u305d\u3082\u305d\u3082Laravel Passport\u3068\u304b\u305d\u3063\u3061\u3067\u304c\u3093\u3070\u308c<br \/>\n\u3068\u3044\u3046\u8a71\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u304c\u3001\u4eca\u56de\u306f\u3001\u30e9\u30a4\u30c8\u306b\u3001\u30e9\u30a4\u30c8\u306b\u3002<\/p>\n<p>app\\Http\\Middleware\\EncryptCookies.php \u306e $except\u306b\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"lang:default decode:true\">    protected $except = [\r\n        'api_token',\r\n    ];\r\n<\/pre>\n<hr \/>\n<h5><span class=\"ez-toc-section\" id=\"API%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0\"><\/span>API\u306e\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>\u8a8d\u8a3c\u304c\u5fc5\u8981\u306aAPI\u306b\u306f\u3001<code>auth:api<\/code>\u306e\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u304c\u5fc5\u8981\u3067\u3059\u3002<br \/>\n\u79c1\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306eroutes\/api.php\u306b\u306f<\/p>\n<pre class=\"lang:default decode:true\">Route::middleware('auth:api')-&gt;get('\/user', function (Request $request) {\r\n    return $request-&gt;user();\r\n});<\/pre>\n<p>\u3059\u3067\u306b\u3044\u3089\u3063\u3057\u3083\u3044\u307e\u3057\u305f\u3002auth:api\u3092\u6301\u3063\u305fAPI\u304c\u3002<br \/>\n\u4ed6\u306b\u3082\u3001\u8a8d\u8a3c\u304c\u5fc5\u8981\u306aAPI\u306f\u3001\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u8a2d\u5b9a\u3067\u8a18\u8ff0\u3059\u308b\u306a\u308a\u3001<br \/>\nController\u306e\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u306b\u8a18\u8ff0\u3059\u308b\u306a\u308a\u3001\u597d\u304d\u306b\u3057\u305f\u3089\u3044\u3044\u3058\u3083\u306a\u3044\u3002<\/p>\n<hr \/>\n<h5><span class=\"ez-toc-section\" id=\"javascript\"><\/span>javascript<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>\u3053\u3053\u307e\u3067Laravel\u306e\u8a2d\u5b9a\u3067\u3057\u305f\u304c\u3001\u3042\u3068\u306fJavascript\u304b\u3089ajax\u901a\u4fe1\u3092\u3057\u307e\u3057\u3087\u3046\u3002<br \/>\n\u3044\u3046\u307e\u3067\u3082\u306a\u304f\u3001\u307f\u3093\u306a\u5927\u597d\u304djQuery\u3067\u3059\u3002<\/p>\n<pre class=\"lang:default decode:true\">    $.ajax({\r\n        'url': '', \/\/ &lt;- \u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u6b21\u7b2c\r\n        'type': 'post', \/\/ &lt;- \u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u6b21\u7b2c\r\n        'dataType': 'json',\r\n        'data': {\r\n            \/\/ \u30ea\u30af\u30a8\u30b9\u30c8\u306eBODY\u90e8\r\n        },\r\n        'headers': {\r\n            'Authorization': 'Bearer ' + Cookies.get('api_token'), \/\/ &lt;- \u3053\u308c\r\n        },\r\n    }).done(function(response){\r\n        alert('success');\r\n    }).fail(function(response){\r\n        alert('error');\r\n    });\r\n<\/pre>\n<p>&nbsp;<br \/>\n\u3042\u3001Cookie\u306e\u53d6\u5f97\u306b\u306f\u3001js-cookie\u3092\u4f7f\u3063\u3066\u307e\u3059\u3002<br \/>\n\u8a73\u3057\u304f\u306f\u30b3\u30c1\u30e9 \u21d2 <a href=\"https:\/\/github.com\/js-cookie\/js-cookie\" rel=\"noopener\" target=\"_blank\">GitHub &#8211; js-cookie\/js-cookie: A simple, lightweight JavaScript API for handling browser cookies<\/a><\/p>\n<p>headers\u306b\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u30d8\u30c3\u30c0\u306b&#8217;Authorization: Bearer [API\u30c8\u30fc\u30af\u30f3]&#8217;\u304c\u542b\u307e\u308c\u308b\u3088\u3046\u306b<br \/>\n\u5024\u3092\u653e\u308a\u8fbc\u3093\u3067\u3044\u307e\u3059\u3002<br \/>\n\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u306f\u3001\u3053\u306e\u30d8\u30c3\u30c0\u306e\u30c8\u30fc\u30af\u30f3\u3092\u898b\u3066\u3001\u78ba\u8a8d\u3092\u3059\u308b\u3088\u3046\u3067\u3059\u306d\u3002<\/p>\n<hr \/>\n<h5><span class=\"ez-toc-section\" id=\"%E6%9C%80%E5%BE%8C%E3%81%AB\"><\/span>\u6700\u5f8c\u306b<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>\u30c8\u30fc\u30af\u30f3\u306e\u6709\u52b9\u671f\u9650\u3092\u30b5\u30fc\u30d0\u3067\u3082\u30c1\u30a7\u30c3\u30af\u3057\u305f\u308a\u3001<br \/>\nusers\u30c6\u30fc\u30d6\u30eb\u306eapi_token\u3092\u30cf\u30c3\u30b7\u30e5\u5316\u3057\u3066\u304a\u3044\u305f\u308a\u3001<br \/>\n\u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u305f\u6642\u306f\u3055\u3059\u304c\u306bapi_token\u3092null\u306b\u3057\u3066\u307f\u305f\u308a\u3001<br \/>\n\u30e6\u30fc\u30b6\u304c\u4efb\u610f\u306b\u30c8\u30fc\u30af\u30f3\u306e\u66f4\u65b0\u3092\u3067\u304d\u308b\u3088\u3046\u306b\u3057\u305f\u308a\u3001<br \/>\n\u306a\u306b\u304b\u3082\u308d\u3082\u308d\u8db3\u308a\u306a\u3044\u611f\u306f\u3042\u308a\u307e\u3059\u304c<br \/>\n\u30e9\u30a4\u30c8\u306b\u3044\u304f\u306a\u3089\u3001\u3053\u3093\u306a\u3082\u306e\u3067\u3057\u3087\u3046\u304b\u3002<\/p>\n<p>Laravel Passport\u306f\u6642\u9593\u304c\u3042\u3063\u305f\u3089\u8a66\u3057\u307e\u3059\u3002<\/p>\n<p>r.tanaka\u304c\u304a\u5c4a\u3051\u3057\u307e\u3057\u305f\u3002<\/p>\n<p>\u3054\u304d\u3052\u3093\u3088\u3046<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u3069\u3046\u3082\u3053\u3093\u306b\u3061\u306f\u3002 Laravel\u3070\u3063\u304b\u308a\u3067\u3059\u3002 \u4eca\u56de\u306f\u3001API\u8a8d\u8a3c\u3067\u3059\u3002 Laravel 5.8\u304b\u3089\u3001API\u8a8d\u8a3c\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u304cPassport\u3092\u4f7f\u308f\u306a\u3044\u65b9\u6cd5\u306b\u306a\u3063\u3066\u307e\u3059\u3002 \u3061\u3087\u3063\u3068\u304a\u8a66\u3057\u3067\u3059\u3002 \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8 \u21d2\u3000AP&#8230;<a class=\"read-more-link button\" href=\"https:\/\/idealive.jp\/blog\/2019\/05\/23\/laravel%e3%81%a7%e8%aa%8d%e8%a8%bc%e3%81%8c%e5%bf%85%e8%a6%81%e3%81%aaapi%e3%82%92%e3%81%94%e3%81%ab%e3%82%87%e3%81%94%e3%81%ab%e3%82%87\/\">\u7d9a\u304d\u3092\u8aad\u3080<\/a><\/p>\n","protected":false},"author":4,"featured_media":685,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,19],"tags":[],"class_list":["post-1509","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel","category-php"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/idealive.jp\/blog\/wp-json\/wp\/v2\/posts\/1509"}],"collection":[{"href":"https:\/\/idealive.jp\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/idealive.jp\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/idealive.jp\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/idealive.jp\/blog\/wp-json\/wp\/v2\/comments?post=1509"}],"version-history":[{"count":4,"href":"https:\/\/idealive.jp\/blog\/wp-json\/wp\/v2\/posts\/1509\/revisions"}],"predecessor-version":[{"id":1513,"href":"https:\/\/idealive.jp\/blog\/wp-json\/wp\/v2\/posts\/1509\/revisions\/1513"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/idealive.jp\/blog\/wp-json\/wp\/v2\/media\/685"}],"wp:attachment":[{"href":"https:\/\/idealive.jp\/blog\/wp-json\/wp\/v2\/media?parent=1509"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/idealive.jp\/blog\/wp-json\/wp\/v2\/categories?post=1509"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/idealive.jp\/blog\/wp-json\/wp\/v2\/tags?post=1509"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}