{"id":3279,"date":"2025-03-24T08:46:32","date_gmt":"2025-03-23T23:46:32","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=3279"},"modified":"2025-03-24T08:47:02","modified_gmt":"2025-03-23T23:47:02","slug":"%e3%80%90%e4%bf%9d%e5%ad%98%e7%89%88%e3%80%91laravel%e3%81%a7%e3%83%ad%e3%82%b0%e3%82%a4%e3%83%b3api%e3%82%92%e5%ae%9f%e8%a3%85%e5%ae%8c%e5%85%a8%e3%81%99%e3%82%8b%e3%82%ac%e3%82%a4%e3%83%892024","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=3279","title":{"rendered":"\u3010\u4fdd\u5b58\u7248\u3011Laravel\u3067\u30ed\u30b0\u30a4\u30f3API\u3092\u5b9f\u88c5\u5b8c\u5168\u3059\u308b\u30ac\u30a4\u30c92024 &#8211; \u8a8d\u8a3c\u6a5f\u80fd\u309215\u5206\u3067\u4f5c\u308b\u65b9\u6cd5"},"content":{"rendered":"\n<div class=\"toc\"><br \/>\n<b>Warning<\/b>:  Undefined array key \"is_admin\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>116<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_category_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>121<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>128<\/b><br \/>\n    <div id=\"toc_container\" class=\"sgb-toc--bullets js-smooth-scroll\" data-dialog-title=\"\u76ee\u6b21\">\n      <p class=\"toc_title\">\u76ee\u6b21 <\/p>\n      <ul class=\"toc_list\">  <li class=\"first\">    <a href=\"#i-0\">Laravel \u306e\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u3068\u306f\uff1f\u57fa\u790e\u77e5\u8b58\u3092\u62bc\u3055\u3048\u3088\u3046<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">Laravel \u30b7\u30b9\u30c6\u30e0\u306e\u7279\u5fb4\u3068\u4e3b\u8981\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-2\">\u3068\u308a\u3042\u3048\u305a\u306e\u8a8d\u8a3c\u6a5f\u80fd\u3067\u5b9f\u73fe\u3067\u304d\u308b\u3053\u3068<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-3\">\u74b0\u5883\u69cb\u7bc9\u304b\u3089\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u5b9f\u88c5\u307e\u3067\u306e\u624b\u9806<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-4\">\u5fc5\u8981\u306a\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3068\u521d\u671f\u8a2d\u5b9a<\/a>      <\/li>      <li>        <a href=\"#i-5\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3068\u30e6\u30fc\u30b6\u30fc\u30e2\u30c7\u30eb\u306e\u6e96\u5099<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-6\">\u30ed\u30b0\u30a4\u30f3\u30d5\u30a9\u30fc\u30e0\u306e\u4f5c\u6210\u3068\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u306e\u8a2d\u5b9a<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-7\">\u8a8d\u8a3c\u51e6\u7406\u306e\u5b9f\u88c5\u30dd\u30a4\u30f3\u30c8<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-8\">\u30e6\u30fc\u30b6\u30fc\u8a8d\u8a3c\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u8a2d\u5b9a<\/a>      <\/li>      <li>        <a href=\"#i-9\">\u30bb\u30ad\u30e5\u30a2\u306a\u30d1\u30b9\u30ef\u30fc\u30c9\u7ba1\u7406\u306e\u5b9f\u88c5\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-10\">\u8a8d\u8a3c\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u306e\u6d3b\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-11\">\u5fdc\u7528\u7684\u306a\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u306e\u5b9f\u88c5\u65b9\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-12\">\u30bd\u30fc\u30b7\u30e3\u30eb\u30ed\u30b0\u30a4\u30f3\u306e\u8ffd\u52a0\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-13\">2\u6bb5\u968e\u8a8d\u8a3c\u306e\u5c0e\u5165\u624b\u9806<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-14\">API \u672c\u4eba\u8a8d\u8a3c\u306e\u5b9f\u88c5\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-15\">\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-16\">\u30af\u30ed\u30b9\u30b5\u30a4\u30c8\u30ea\u30af\u30a8\u30b9\u30c8\u30d5\u30a9\u30fc\u30b8\u30a7\u30ea\u5bfe\u7b56<\/a>      <\/li>      <li>        <a href=\"#i-17\">\u30d6\u30eb\u30fc\u30c8\u30d5\u30a9\u30fc\u30b9\u653b\u6483\u3078\u306e\u5bfe\u51e6\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-18\">\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-19\">\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u3068\u30c7\u30d0\u30c3\u30b0<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-20\">\u3088\u304f\u3042\u308b\u30a8\u30e9\u30fc\u3068\u305d\u306e\u89e3\u6c7a\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-21\">\u30ed\u30b0\u30a4\u30f3\u51e6\u7406\u306e\u52d5\u4f5c\u78ba\u8a8d\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-22\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u30dd\u30a4\u30f3\u30c8<\/a>      <\/li>    <\/ul>  <\/li><\/ul>\n      <a href=\"#\" class=\"sgb-toc-button js-toc-button\" rel=\"nofollow\" data-open-dialog=\"true\"><i class=\"fa fa-list\"><\/i><span class=\"sgb-toc-button__text\">\u76ee\u6b21\u3078<\/span><\/a>\n    <\/div><\/div><h2 class=\"wp-block-heading\" id=\"i-0\">Laravel \u306e\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u3068\u306f\uff1f\u57fa\u790e\u77e5\u8b58\u3092\u62bc\u3055\u3048\u3088\u3046<\/h2>\n\n\n\n<p>Laravel\u306e\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u306f\u3001Web\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u304a\u3051\u308b\u30e6\u30fc\u30b6\u30fc\u8a8d\u8a3c\u3092\u7c21\u5358\u304b\u3064\u30bb\u30ad\u30e5\u30a2\u306b\u5b9f\u88c5\u3067\u304d\u308b\u6a5f\u80fd\u3067\u3059\u3002\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u7279\u5fb4\u3067\u3042\u308b\u512a\u308c\u305f\u62bd\u8c61\u5316\u3068\u5805\u7262\u306a\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u6a5f\u80fd\u306b\u3088\u308a\u3001\u77ed\u6642\u9593\u3067\u672c\u756a\u74b0\u5883\u306b\u5c0e\u5165\u53ef\u80fd\u306a\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-1\">Laravel \u30b7\u30b9\u30c6\u30e0\u306e\u7279\u5fb4\u3068\u4e3b\u8981\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8<\/h3>\n\n\n\n<p>Laravel\u306e\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u306f\u4ee5\u4e0b\u306e\u4e3b\u8981\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067\u69cb\u6210\u3055\u308c\u3066\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Auth \u30d5\u30a1\u30b5\u30fc\u30c9<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30e6\u30fc\u30b6\u30fc\u306e\u8a8d\u8a3c\u72b6\u614b\u306e\u78ba\u8a8d<\/li>\n\n\n\n<li>\u30ed\u30b0\u30a4\u30f3\u30fb\u30ed\u30b0\u30a2\u30a6\u30c8\u51e6\u7406\u306e\u5b9f\u884c<\/li>\n\n\n\n<li>\u73fe\u5728\u306e\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u306e\u53d6\u5f97<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Guard\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u8a8d\u8a3c\u65b9\u5f0f\u306e\u5b9a\u7fa9\uff08\u30bb\u30c3\u30b7\u30e7\u30f3\u3001\u30c8\u30fc\u30af\u30f3\u306a\u3069\uff09<\/li>\n\n\n\n<li>\u30ab\u30b9\u30bf\u30e0\u8a8d\u8a3c\u30ed\u30b8\u30c3\u30af\u306e\u5b9f\u88c5\u304c\u53ef\u80fd<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>User\u30d7\u30ed\u30d0\u30a4\u30c0<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u306e\u53d6\u5f97\u65b9\u6cd5\u3092\u5b9a\u7fa9<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3084\u305d\u306e\u4ed6\u306e\u30b9\u30c8\u30ec\u30fc\u30b8\u3068\u306e\u9023\u643a<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30df\u30c9\u30eb\u30a6\u30a7\u30a2<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30eb\u30fc\u30c8\u306e\u4fdd\u8b77<\/li>\n\n\n\n<li>\u8a8d\u8a3c\u72b6\u614b\u306b\u57fa\u3065\u304f\u30a2\u30af\u30bb\u30b9\u5236\u5fa1<\/li>\n<\/ul>\n\n\n\n<p>\u4e3b\u306a\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306f <code>config\/auth.php<\/code> \u3067\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u69cb\u6210\u306b\u306a\u3063\u3066\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">return [\n    'defaults' =&gt; [\n        'guard' =&gt; 'web',\n        'passwords' =&gt; 'users',\n    ],\n\n    'guards' =&gt; [\n        'web' =&gt; [\n            'driver' =&gt; 'session',\n            'provider' =&gt; 'users',\n        ],\n        'api' =&gt; [\n            'driver' =&gt; 'token',\n            'provider' =&gt; 'users',\n        ],\n    ],\n    \/\/ ...\n];<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-2\">\u3068\u308a\u3042\u3048\u305a\u306e\u8a8d\u8a3c\u6a5f\u80fd\u3067\u5b9f\u73fe\u3067\u304d\u308b\u3053\u3068<\/h3>\n\n\n\n<p>\u57fa\u672c\u7684\u306a\u8a8d\u8a3c\u6a5f\u80fd\u3092\u5b9f\u88c5\u3059\u308b\u3060\u3051\u3067\u3082\u3001\u4ee5\u4e0b\u306e\u6a5f\u80fd\u304c\u5229\u7528\u53ef\u80fd\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30e6\u30fc\u30b6\u30fc\u767b\u9332\u6a5f\u80fd<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u65b0\u898f\u30e6\u30fc\u30b6\u30fc\u306e\u4f5c\u6210<\/li>\n\n\n\n<li>\u30e1\u30fc\u30eb\u78ba\u8a8d\u6a5f\u80fd\uff08\u30aa\u30d7\u30b7\u30e7\u30f3\uff09<\/li>\n\n\n\n<li>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u6a5f\u80fd<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ed\u30b0\u30a4\u30f3\/\u30ed\u30b0\u30a2\u30a6\u30c8\u6a5f\u80fd<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u30d9\u30fc\u30b9\u306e\u8a8d\u8a3c<\/li>\n\n\n\n<li>Remember Me\u6a5f\u80fd<\/li>\n\n\n\n<li>\u30ed\u30b0\u30a4\u30f3\u8a66\u884c\u56de\u6570\u306e\u5236\u9650<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d1\u30b9\u30ef\u30fc\u30c9\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5b89\u5168\u306a\u30d1\u30b9\u30ef\u30fc\u30c9\u30cf\u30c3\u30b7\u30e5\u5316<\/li>\n\n\n\n<li>\u30d1\u30b9\u30ef\u30fc\u30c9\u30ea\u30bb\u30c3\u30c8\u6a5f\u80fd<\/li>\n\n\n\n<li>\u30d1\u30b9\u30ef\u30fc\u30c9\u5f37\u5ea6\u306e\u691c\u8a3c<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u8a8d\u8a3c\u72b6\u614b\u306e\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u306b\u3088\u308b\u30eb\u30fc\u30c8\u4fdd\u8b77<\/li>\n\n\n\n<li>\u8a8d\u8a3c\u72b6\u614b\u306e\u78ba\u8a8d<\/li>\n\n\n\n<li>\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u3078\u306e\u30a2\u30af\u30bb\u30b9<\/li>\n<\/ul>\n\n\n\n<p>\u7c21\u5358\u306a\u4f7f\u7528\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30eb\u30fc\u30c8\u306e\u4fdd\u8b77\nRoute::middleware('auth')-&gt;group(function () {\n    Route::get('\/dashboard', function () {\n        return view('dashboard');\n    });\n});\n\n\/\/ \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u3067\u306e\u8a8d\u8a3c\u72b6\u614b\u78ba\u8a8d\npublic function index()\n{\n    if (Auth::check()) {\n        $user = Auth::user();\n        return view('dashboard', compact('user'));\n    }\n    return redirect('\/login');\n}<\/pre>\n\n\n\n<p>\u3053\u306e\u57fa\u672c\u6a5f\u80fd\u3092\u571f\u53f0\u3068\u3057\u3066\u3001\u5f8c\u307b\u3069\u8aac\u660e\u3059\u308b\u9ad8\u5ea6\u306a\u8a8d\u8a3c\u6a5f\u80fd\uff08\u30bd\u30fc\u30b7\u30e3\u30eb\u30ed\u30b0\u30a4\u30f3\u30842\u6bb5\u968e\u8a8d\u8a3c\u306a\u3069\uff09\u3092\u8ffd\u52a0\u5b9f\u88c5\u3059\u308b\u3053\u3068\u304c\u53ef\u80fd\u3067\u3059\u3002\u3053\u308c\u306b\u3088\u308a\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30ec\u30d9\u30eb\u3068\u5229\u4fbf\u6027\u3092\u6bb5\u968e\u7684\u306b\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-3\">\u74b0\u5883\u69cb\u7bc9\u304b\u3089\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u5b9f\u88c5\u307e\u3067\u306e\u624b\u9806<\/h2>\n\n\n\n<p>\u3053\u3053\u3067\u306f\u3001Laravel\u306e\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u3092\u5b9f\u88c5\u3059\u308b\u305f\u3081\u306e\u5177\u4f53\u7684\u306a\u624b\u9806\u3092\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-4\">\u5fc5\u8981\u306a\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3068\u521d\u671f\u8a2d\u5b9a<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u65b0\u898f\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">composer create-project laravel\/laravel login-app\ncd login-app<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u8a8d\u8a3c\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">composer require laravel\/ui\nphp artisan ui bootstrap --auth\nnpm install &amp;&amp; npm run dev<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>.env \u30d5\u30a1\u30a4\u30eb\u306e\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">DB_CONNECTION=mysql\nDB_HOST=127.0.0.1\nDB_PORT=3306\nDB_DATABASE=login_app\nDB_USERNAME=root\nDB_PASSWORD=your_password<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3068\u30e6\u30fc\u30b6\u30fc\u30e2\u30c7\u30eb\u306e\u6e96\u5099<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u4f5c\u6210<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CREATE DATABASE login_app;<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u884c<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">php artisan migrate<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30e6\u30fc\u30b6\u30fc\u30e2\u30c7\u30eb\u306e\u62e1\u5f35<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Models\/User.php\nnamespace App\\Models;\n\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\nuse Illuminate\\Notifications\\Notifiable;\nuse Laravel\\Sanctum\\HasApiTokens;\n\nclass User extends Authenticatable\n{\n    use HasApiTokens, Notifiable;\n\n    protected $fillable = [\n        'name',\n        'email',\n        'password',\n    ];\n\n    protected $hidden = [\n        'password',\n        'remember_token',\n    ];\n\n    protected $casts = [\n        'email_verified_at' =&gt; 'datetime',\n        'password' =&gt; 'hashed',\n    ];\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-6\">\u30ed\u30b0\u30a4\u30f3\u30d5\u30a9\u30fc\u30e0\u306e\u4f5c\u6210\u3068\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u306e\u8a2d\u5b9a<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ed\u30b0\u30a4\u30f3\u30d5\u30a9\u30fc\u30e0\u306e\u4f5c\u6210<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ resources\/views\/auth\/login.blade.php\n@extends('layouts.app')\n\n@section('content')\n&lt;div class=\"container\"&gt;\n    &lt;div class=\"row justify-content-center\"&gt;\n        &lt;div class=\"col-md-8\"&gt;\n            &lt;div class=\"card\"&gt;\n                &lt;div class=\"card-header\"&gt;{{ __('Login') }}&lt;\/div&gt;\n\n                &lt;div class=\"card-body\"&gt;\n                    &lt;form method=\"POST\" action=\"{{ route('login') }}\"&gt;\n                        @csrf\n                        &lt;div class=\"form-group row\"&gt;\n                            &lt;label for=\"email\"&gt;{{ __('Email') }}&lt;\/label&gt;\n                            &lt;input id=\"email\" type=\"email\" name=\"email\" required autofocus&gt;\n                        &lt;\/div&gt;\n\n                        &lt;div class=\"form-group row\"&gt;\n                            &lt;label for=\"password\"&gt;{{ __('Password') }}&lt;\/label&gt;\n                            &lt;input id=\"password\" type=\"password\" name=\"password\" required&gt;\n                        &lt;\/div&gt;\n\n                        &lt;div class=\"form-group row\"&gt;\n                            &lt;div class=\"form-check\"&gt;\n                                &lt;input type=\"checkbox\" name=\"remember\" id=\"remember\"&gt;\n                                &lt;label for=\"remember\"&gt;{{ __('Remember Me') }}&lt;\/label&gt;\n                            &lt;\/div&gt;\n                        &lt;\/div&gt;\n\n                        &lt;div class=\"form-group row mb-0\"&gt;\n                            &lt;button type=\"submit\"&gt;\n                                {{ __('Login') }}\n                            &lt;\/button&gt;\n                        &lt;\/div&gt;\n                    &lt;\/form&gt;\n                &lt;\/div&gt;\n            &lt;\/div&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;\n&lt;\/div&gt;\n@endsection<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u306e\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ routes\/web.php\nuse App\\Http\\Controllers\\Auth\\LoginController;\n\nRoute::middleware(['guest'])-&gt;group(function () {\n    Route::get('login', [LoginController::class, 'showLoginForm'])-&gt;name('login');\n    Route::post('login', [LoginController::class, 'login']);\n});\n\nRoute::middleware(['auth'])-&gt;group(function () {\n    Route::post('logout', [LoginController::class, 'logout'])-&gt;name('logout');\n    Route::get('\/dashboard', function () {\n        return view('dashboard');\n    })-&gt;name('dashboard');\n});<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u624b\u9806\u3092\u5b9f\u884c\u3059\u308b\u3053\u3068\u3067\u3001\u57fa\u672c\u7684\u306a\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u304c\u5b9f\u88c5\u3055\u308c\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u306e\u57fa\u672c\u5b9f\u88c5\u306b\u5bfe\u3059\u308b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5f37\u5316\u3068\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-7\">\u8a8d\u8a3c\u51e6\u7406\u306e\u5b9f\u88c5\u30dd\u30a4\u30f3\u30c8<\/h2>\n\n\n\n<p>Laravel\u3067\u306e\u8a8d\u8a3c\u51e6\u7406\u5b9f\u88c5\u306b\u304a\u3044\u3066\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3068\u4f7f\u3044\u3084\u3059\u3055\u3092\u4e21\u7acb\u3059\u308b\u305f\u3081\u306e\u91cd\u8981\u306a\u30dd\u30a4\u30f3\u30c8\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-8\">\u30e6\u30fc\u30b6\u30fc\u8a8d\u8a3c\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u8a2d\u5b9a<\/h3>\n\n\n\n<p>\u30e6\u30fc\u30b6\u30fc\u5165\u529b\u306e\u691c\u8a3c\u306f\u3001\u30bb\u30ad\u30e5\u30a2\u306a\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u306e\u57fa\u672c\u3068\u306a\u308a\u307e\u3059\u3002Laravel\u3067\u306f\u3001FormRequest\u3092\u4f7f\u7528\u3057\u3066\u5805\u7262\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u88c5\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u57fa\u672c\u7684\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Requests\/Auth\/LoginRequest.php\nnamespace App\\Http\\Requests\\Auth;\n\nuse Illuminate\\Auth\\Events\\Lockout;\nuse Illuminate\\Foundation\\Http\\FormRequest;\nuse Illuminate\\Support\\Facades\\Auth;\nuse Illuminate\\Support\\Facades\\RateLimiter;\nuse Illuminate\\Validation\\ValidationException;\n\nclass LoginRequest extends FormRequest\n{\n    public function rules()\n    {\n        return [\n            'email' =&gt; [\n                'required',\n                'string',\n                'email',\n                'exists:users',\n                'max:255'\n            ],\n            'password' =&gt; [\n                'required',\n                'string',\n                'min:8'\n            ],\n            'remember' =&gt; 'boolean'\n        ];\n    }\n\n    \/\/ \u30ec\u30fc\u30c8\u5236\u9650\u306e\u5b9f\u88c5\n    public function authenticate()\n    {\n        $this-&gt;ensureIsNotRateLimited();\n\n        if (!Auth::attempt(\n            $this-&gt;only('email', 'password'),\n            $this-&gt;boolean('remember')\n        )) {\n            RateLimiter::hit($this-&gt;throttleKey());\n\n            throw ValidationException::withMessages([\n                'email' =&gt; __('auth.failed'),\n            ]);\n        }\n\n        RateLimiter::clear($this-&gt;throttleKey());\n    }\n\n    \/\/ \u30ec\u30fc\u30c8\u5236\u9650\u306e\u30c1\u30a7\u30c3\u30af\n    protected function ensureIsNotRateLimited()\n    {\n        if (RateLimiter::tooManyAttempts($this-&gt;throttleKey(), 5)) {\n            event(new Lockout($this));\n\n            $seconds = RateLimiter::availableIn($this-&gt;throttleKey());\n\n            throw ValidationException::withMessages([\n                'email' =&gt; __('auth.throttle', [\n                    'seconds' =&gt; $seconds,\n                    'minutes' =&gt; ceil($seconds \/ 60),\n                ]),\n            ]);\n        }\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-9\">\u30bb\u30ad\u30e5\u30a2\u306a\u30d1\u30b9\u30ef\u30fc\u30c9\u7ba1\u7406\u306e\u5b9f\u88c5\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u30d1\u30b9\u30ef\u30fc\u30c9\u7ba1\u7406\u3067\u306f\u3001\u30cf\u30c3\u30b7\u30e5\u5316\u3068\u5b89\u5168\u306a\u691c\u8a3c\u30d7\u30ed\u30bb\u30b9\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d1\u30b9\u30ef\u30fc\u30c9\u30cf\u30c3\u30b7\u30e5\u5316\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Controllers\/Auth\/RegisterController.php\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse App\\Models\\User;\nuse Illuminate\\Support\\Facades\\Hash;\nuse App\\Http\\Requests\\Auth\\RegisterRequest;\n\nclass RegisterController extends Controller\n{\n    public function store(RegisterRequest $request)\n    {\n        $user = User::create([\n            'name' =&gt; $request-&gt;name,\n            'email' =&gt; $request-&gt;email,\n            'password' =&gt; Hash::make($request-&gt;password),\n        ]);\n\n        \/\/ \u30d1\u30b9\u30ef\u30fc\u30c9\u5f37\u5ea6\u306e\u691c\u8a3c\u3068\u5c65\u6b74\u7ba1\u7406\n        $this-&gt;validatePasswordStrength($request-&gt;password);\n        $this-&gt;storePasswordHistory($user-&gt;id, $request-&gt;password);\n\n        return response()-&gt;json([\n            'message' =&gt; '\u30e6\u30fc\u30b6\u30fc\u767b\u9332\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f'\n        ], 201);\n    }\n\n    private function validatePasswordStrength($password)\n    {\n        $requirements = [\n            'length' =&gt; strlen($password) &gt;= 8,\n            'uppercase' =&gt; preg_match('\/[A-Z]\/', $password),\n            'lowercase' =&gt; preg_match('\/[a-z]\/', $password),\n            'numbers' =&gt; preg_match('\/[0-9]\/', $password),\n            'special' =&gt; preg_match('\/[^A-Za-z0-9]\/', $password),\n        ];\n\n        if (in_array(false, $requirements)) {\n            throw ValidationException::withMessages([\n                'password' =&gt; '\u30d1\u30b9\u30ef\u30fc\u30c9\u306f8\u6587\u5b57\u4ee5\u4e0a\u3067\u3001\u5927\u6587\u5b57\u3001\u5c0f\u6587\u5b57\u3001\u6570\u5b57\u3001\u7279\u6b8a\u6587\u5b57\u3092\u542b\u3080\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002'\n            ]);\n        }\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-10\">\u8a8d\u8a3c\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u306e\u6d3b\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<p>\u8a8d\u8a3c\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u3092\u4f7f\u7528\u3057\u3066\u3001\u52b9\u679c\u7684\u306a\u30a2\u30af\u30bb\u30b9\u5236\u5fa1\u3092\u5b9f\u88c5\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ab\u30b9\u30bf\u30e0\u8a8d\u8a3c\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Middleware\/AuthenticateWithSession.php\nnamespace App\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Auth\\Middleware\\Authenticate as Middleware;\nuse Illuminate\\Support\\Facades\\Auth;\n\nclass AuthenticateWithSession extends Middleware\n{\n    public function handle($request, Closure $next, ...$guards)\n    {\n        if (!Auth::check()) {\n            return $request-&gt;expectsJson()\n                ? response()-&gt;json(['message' =&gt; '\u8a8d\u8a3c\u304c\u5fc5\u8981\u3067\u3059'], 401)\n                : redirect()-&gt;guest(route('login'));\n        }\n\n        \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u6709\u52b9\u671f\u9650\u30c1\u30a7\u30c3\u30af\n        $user = Auth::user();\n        if ($user-&gt;last_activity &amp;&amp; \n            now()-&gt;diffInMinutes($user-&gt;last_activity) &gt; config('session.lifetime')) {\n            Auth::logout();\n            return redirect()-&gt;route('login')\n                -&gt;with('message', '\u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u6709\u52b9\u671f\u9650\u304c\u5207\u308c\u307e\u3057\u305f');\n        }\n\n        \/\/ \u6700\u7d42\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u6642\u9593\u306e\u66f4\u65b0\n        $user-&gt;last_activity = now();\n        $user-&gt;save();\n\n        return $next($request);\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u306e\u9069\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ routes\/web.php\nRoute::middleware(['auth.session'])-&gt;group(function () {\n    Route::get('\/dashboard', [DashboardController::class, 'index'])\n        -&gt;name('dashboard');\n\n    Route::get('\/profile', [ProfileController::class, 'show'])\n        -&gt;name('profile');\n\n    Route::post('\/logout', [AuthController::class, 'logout'])\n        -&gt;name('logout');\n});<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5b9f\u88c5\u306b\u3088\u308a\u3001\u4ee5\u4e0b\u306e\u6a5f\u80fd\u304c\u5b9f\u73fe\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u53b3\u5bc6\u306a\u30d1\u30b9\u30ef\u30fc\u30c9\u30dd\u30ea\u30b7\u30fc\u306e\u9069\u7528<\/li>\n\n\n\n<li>\u30d6\u30eb\u30fc\u30c8\u30d5\u30a9\u30fc\u30b9\u653b\u6483\u5bfe\u7b56\uff08\u30ec\u30fc\u30c8\u5236\u9650\uff09<\/li>\n\n\n\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406\u306e\u6700\u9069\u5316<\/li>\n\n\n\n<li>\u5b89\u5168\u306a\u30d1\u30b9\u30ef\u30fc\u30c9\u30ea\u30bb\u30c3\u30c8\u6a5f\u80fd<\/li>\n\n\n\n<li>\u30a2\u30af\u30bb\u30b9\u5236\u5fa1\u306e\u4e00\u5143\u7ba1\u7406<\/li>\n<\/ul>\n\n\n\n<p>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u9762\u3067\u306e\u6ce8\u610f\u70b9\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30d1\u30b9\u30ef\u30fc\u30c9\u306f\u5fc5\u305a\u30cf\u30c3\u30b7\u30e5\u5316\u3057\u3066\u4fdd\u5b58<\/li>\n\n\n\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u30cf\u30a4\u30b8\u30e3\u30c3\u30af\u5bfe\u7b56\u3068\u3057\u3066\u30bb\u30c3\u30b7\u30e7\u30f3ID\u306e\u518d\u751f\u6210<\/li>\n\n\n\n<li>\u30af\u30ed\u30b9\u30b5\u30a4\u30c8\u30ea\u30af\u30a8\u30b9\u30c8\u30d5\u30a9\u30fc\u30b8\u30a7\u30ea\uff08CSRF\uff09\u5bfe\u7b56\u306e\u5b9f\u65bd<\/li>\n\n\n\n<li>\u30ec\u30fc\u30c8\u5236\u9650\u306b\u3088\u308b\u653b\u6483\u306e\u9632\u6b62<\/li>\n\n\n\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u306e\u9069\u5207\u306a\u8a2d\u5b9a<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-11\">\u5fdc\u7528\u7684\u306a\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u306e\u5b9f\u88c5\u65b9\u6cd5<\/h2>\n\n\n\n<p>\u57fa\u672c\u7684\u306a\u8a8d\u8a3c\u6a5f\u80fd\u306b\u52a0\u3048\u3066\u3001\u3088\u308a\u9ad8\u5ea6\u306a\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3068\u5229\u4fbf\u6027\u3092\u5b9f\u73fe\u3059\u308b\u305f\u3081\u306e\u6a5f\u80fd\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-12\">\u30bd\u30fc\u30b7\u30e3\u30eb\u30ed\u30b0\u30a4\u30f3\u306e\u8ffd\u52a0\u5b9f\u88c5<\/h3>\n\n\n\n<p>Laravel\u3067\u30bd\u30fc\u30b7\u30e3\u30eb\u30ed\u30b0\u30a4\u30f3\u3092\u5b9f\u88c5\u3059\u308b\u969b\u306f\u3001Laravel Socialite\u30d1\u30c3\u30b1\u30fc\u30b8\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u521d\u671f\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Socialite\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\ncomposer require laravel\/socialite\n\n# \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u4f5c\u6210\nphp artisan make:migration add_social_auth_columns_to_users_table<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ database\/migrations\/xxxx_xx_xx_add_social_auth_columns_to_users_table.php\npublic function up()\n{\n    Schema::table('users', function (Blueprint $table) {\n        $table-&gt;string('provider_name')-&gt;nullable();\n        $table-&gt;string('provider_id')-&gt;nullable();\n        $table-&gt;string('provider_token')-&gt;nullable();\n        $table-&gt;string('provider_refresh_token')-&gt;nullable();\n    });\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ config\/services.php\nreturn [\n    'google' =&gt; [\n        'client_id' =&gt; env('GOOGLE_CLIENT_ID'),\n        'client_secret' =&gt; env('GOOGLE_CLIENT_SECRET'),\n        'redirect' =&gt; env('GOOGLE_CALLBACK_URL'),\n    ],\n];\n\n\/\/ routes\/web.php\nRoute::get('login\/{provider}', [SocialLoginController::class, 'redirect'])\n    -&gt;name('social.login');\nRoute::get('login\/{provider}\/callback', [SocialLoginController::class, 'callback'])\n    -&gt;name('social.callback');<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Controllers\/Auth\/SocialLoginController.php\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse App\\Models\\User;\nuse Laravel\\Socialite\\Facades\\Socialite;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Log;\n\nclass SocialLoginController extends Controller\n{\n    public function redirect($provider)\n    {\n        return Socialite::driver($provider)\n            -&gt;with(['prompt' =&gt; 'select_account'])\n            -&gt;redirect();\n    }\n\n    public function callback($provider)\n    {\n        try {\n            DB::beginTransaction();\n\n            $socialUser = Socialite::driver($provider)-&gt;user();\n\n            $user = User::where('email', $socialUser-&gt;getEmail())-&gt;first();\n\n            if (!$user) {\n                $user = User::create([\n                    'name' =&gt; $socialUser-&gt;getName(),\n                    'email' =&gt; $socialUser-&gt;getEmail(),\n                    'provider_name' =&gt; $provider,\n                    'provider_id' =&gt; $socialUser-&gt;getId(),\n                    'provider_token' =&gt; $socialUser-&gt;token,\n                    'provider_refresh_token' =&gt; $socialUser-&gt;refreshToken,\n                    'email_verified_at' =&gt; now(),\n                ]);\n            } else {\n                \/\/ \u65e2\u5b58\u30e6\u30fc\u30b6\u30fc\u306e\u5834\u5408\u306f\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u60c5\u5831\u3092\u66f4\u65b0\n                $user-&gt;update([\n                    'provider_name' =&gt; $provider,\n                    'provider_id' =&gt; $socialUser-&gt;getId(),\n                    'provider_token' =&gt; $socialUser-&gt;token,\n                    'provider_refresh_token' =&gt; $socialUser-&gt;refreshToken,\n                ]);\n            }\n\n            DB::commit();\n            auth()-&gt;login($user, true);\n\n            return redirect()-&gt;route('dashboard');\n\n        } catch (\\Exception $e) {\n            DB::rollBack();\n            Log::error('\u30bd\u30fc\u30b7\u30e3\u30eb\u30ed\u30b0\u30a4\u30f3\u30a8\u30e9\u30fc: ' . $e-&gt;getMessage());\n\n            return redirect()-&gt;route('login')\n                -&gt;withErrors(['social' =&gt; '\u30bd\u30fc\u30b7\u30e3\u30eb\u30ed\u30b0\u30a4\u30f3\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002']);\n        }\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">2\u6bb5\u968e\u8a8d\u8a3c\u306e\u5c0e\u5165\u624b\u9806<\/h3>\n\n\n\n<p>Google Authenticator\u306a\u3069\u306e\u30ef\u30f3\u30bf\u30a4\u30e0\u30d1\u30b9\u30ef\u30fc\u30c9\uff08TOTP\uff09\u3092\u4f7f\u7528\u3057\u305f2\u6bb5\u968e\u8a8d\u8a3c\u3092\u5b9f\u88c5\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5fc5\u8981\u306a\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u5c0e\u5165<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">composer require pragmarx\/google2fa-laravel bacon\/bacon-qr-code\nphp artisan make:migration add_2fa_columns_to_users_table<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ database\/migrations\/xxxx_xx_xx_add_2fa_columns_to_users_table.php\npublic function up()\n{\n    Schema::table('users', function (Blueprint $table) {\n        $table-&gt;boolean('two_factor_enabled')-&gt;default(false);\n        $table-&gt;string('two_factor_secret')-&gt;nullable();\n        $table-&gt;json('two_factor_recovery_codes')-&gt;nullable();\n    });\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>2\u6bb5\u968e\u8a8d\u8a3c\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Controllers\/Auth\/TwoFactorAuthController.php\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse PragmaRX\\Google2FA\\Google2FA;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Str;\n\nclass TwoFactorAuthController extends Controller\n{\n    private $google2fa;\n\n    public function __construct()\n    {\n        $this-&gt;google2fa = new Google2FA();\n    }\n\n    public function enable(Request $request)\n    {\n        $user = $request-&gt;user();\n\n        if (!$user-&gt;two_factor_secret) {\n            \/\/ \u65b0\u898f\u30b7\u30fc\u30af\u30ec\u30c3\u30c8\u30ad\u30fc\u306e\u751f\u6210\n            $user-&gt;two_factor_secret = $this-&gt;google2fa-&gt;generateSecretKey();\n\n            \/\/ \u30ea\u30ab\u30d0\u30ea\u30fc\u30b3\u30fc\u30c9\u306e\u751f\u6210\n            $user-&gt;two_factor_recovery_codes = json_encode(\n                collect(range(1, 8))-&gt;map(function () {\n                    return Str::random(10);\n                })-&gt;all()\n            );\n\n            $user-&gt;save();\n        }\n\n        $qrCodeUrl = $this-&gt;google2fa-&gt;getQRCodeUrl(\n            config('app.name'),\n            $user-&gt;email,\n            $user-&gt;two_factor_secret\n        );\n\n        return view('auth.2fa.enable', [\n            'qrCodeUrl' =&gt; $qrCodeUrl,\n            'secret' =&gt; $user-&gt;two_factor_secret,\n            'recoveryCodes' =&gt; json_decode($user-&gt;two_factor_recovery_codes)\n        ]);\n    }\n\n    public function verify(Request $request)\n    {\n        $request-&gt;validate(['code' =&gt; 'required|string|size:6']);\n\n        $user = $request-&gt;user();\n        $valid = $this-&gt;google2fa-&gt;verifyKey(\n            $user-&gt;two_factor_secret,\n            $request-&gt;code\n        );\n\n        if ($valid) {\n            $user-&gt;two_factor_enabled = true;\n            $user-&gt;save();\n\n            return redirect()-&gt;route('dashboard')\n                -&gt;with('status', '2\u6bb5\u968e\u8a8d\u8a3c\u304c\u6709\u52b9\u5316\u3055\u308c\u307e\u3057\u305f');\n        }\n\n        return back()-&gt;withErrors(['code' =&gt; '\u8a8d\u8a3c\u30b3\u30fc\u30c9\u304c\u7121\u52b9\u3067\u3059']);\n    }\n\n    public function disable(Request $request)\n    {\n        $user = $request-&gt;user();\n        $user-&gt;two_factor_enabled = false;\n        $user-&gt;two_factor_secret = null;\n        $user-&gt;two_factor_recovery_codes = null;\n        $user-&gt;save();\n\n        return redirect()-&gt;route('profile.show')\n            -&gt;with('status', '2\u6bb5\u968e\u8a8d\u8a3c\u304c\u7121\u52b9\u5316\u3055\u308c\u307e\u3057\u305f');\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-14\">API \u672c\u4eba\u8a8d\u8a3c\u306e\u5b9f\u88c5\u65b9\u6cd5<\/h3>\n\n\n\n<p>Laravel Sanctum\u3092\u4f7f\u7528\u3057\u305fAPI\u30c8\u30fc\u30af\u30f3\u8a8d\u8a3c\u306e\u5b9f\u88c5\u65b9\u6cd5\u3067\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u521d\u671f\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">composer require laravel\/sanctum\nphp artisan vendor:publish --provider=\"Laravel\\Sanctum\\SanctumServiceProvider\"\nphp artisan migrate<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>API\u8a8d\u8a3c\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Controllers\/Auth\/ApiTokenController.php\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse App\\Models\\User;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Hash;\nuse Illuminate\\Validation\\ValidationException;\n\nclass ApiTokenController extends Controller\n{\n    public function issueToken(Request $request)\n    {\n        $request-&gt;validate([\n            'email' =&gt; ['required', 'email'],\n            'password' =&gt; ['required'],\n            'device_name' =&gt; ['required', 'string'],\n        ]);\n\n        $user = User::where('email', $request-&gt;email)-&gt;first();\n\n        if (!$user || !Hash::check($request-&gt;password, $user-&gt;password)) {\n            throw ValidationException::withMessages([\n                'email' =&gt; ['\u8a8d\u8a3c\u60c5\u5831\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\u3002'],\n            ]);\n        }\n\n        \/\/ \u30c7\u30d0\u30a4\u30b9\u3054\u3068\u306e\u30c8\u30fc\u30af\u30f3\u7ba1\u7406\n        $existingToken = $user-&gt;tokens()\n            -&gt;where('name', $request-&gt;device_name)\n            -&gt;first();\n\n        if ($existingToken) {\n            $existingToken-&gt;delete();\n        }\n\n        $token = $user-&gt;createToken($request-&gt;device_name, [\n            'read',\n            'create',\n            'update'\n        ]);\n\n        return response()-&gt;json([\n            'token' =&gt; $token-&gt;plainTextToken,\n            'abilities' =&gt; $token-&gt;accessToken-&gt;abilities,\n            'user' =&gt; [\n                'id' =&gt; $user-&gt;id,\n                'name' =&gt; $user-&gt;name,\n                'email' =&gt; $user-&gt;email,\n            ]\n        ]);\n    }\n\n    public function revokeToken(Request $request)\n    {\n        \/\/ \u73fe\u5728\u306e\u30c8\u30fc\u30af\u30f3\u3092\u524a\u9664\n        $request-&gt;user()-&gt;currentAccessToken()-&gt;delete();\n\n        return response()-&gt;json([\n            'message' =&gt; '\u30c8\u30fc\u30af\u30f3\u304c\u6b63\u5e38\u306b\u524a\u9664\u3055\u308c\u307e\u3057\u305f\u3002'\n        ]);\n    }\n\n    public function revokeAllTokens(Request $request)\n    {\n        \/\/ \u3059\u3079\u3066\u306e\u30c8\u30fc\u30af\u30f3\u3092\u524a\u9664\n        $request-&gt;user()-&gt;tokens()-&gt;delete();\n\n        return response()-&gt;json([\n            'message' =&gt; '\u3059\u3079\u3066\u306e\u30c8\u30fc\u30af\u30f3\u304c\u524a\u9664\u3055\u308c\u307e\u3057\u305f\u3002'\n        ]);\n    }\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30eb\u30fc\u30c8\u306e\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ routes\/api.php\nRoute::post('\/tokens\/create', [ApiTokenController::class, 'issueToken'])\n    -&gt;middleware('guest');\n\nRoute::middleware('auth:sanctum')-&gt;group(function () {\n    Route::post('\/tokens\/revoke', [ApiTokenController::class, 'revokeToken']);\n    Route::post('\/tokens\/revoke-all', [ApiTokenController::class, 'revokeAllTokens']);\n\n    \/\/ \u4fdd\u8b77\u3055\u308c\u305fAPI\u30eb\u30fc\u30c8\n    Route::get('\/user', function (Request $request) {\n        return $request-&gt;user();\n    });\n});<\/pre>\n\n\n\n<p>\u5404\u6a5f\u80fd\u5b9f\u88c5\u6642\u306e\u91cd\u8981\u306a\u30dd\u30a4\u30f3\u30c8\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30bd\u30fc\u30b7\u30e3\u30eb\u30ed\u30b0\u30a4\u30f3<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3054\u3068\u306e\u9069\u5207\u306a\u30b9\u30b3\u30fc\u30d7\u8a2d\u5b9a<\/li>\n\n\n\n<li>\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u7ba1\u7406\u306b\u3088\u308b\u6574\u5408\u6027\u306e\u78ba\u4fdd<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>2\u6bb5\u968e\u8a8d\u8a3c<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30ea\u30ab\u30d0\u30ea\u30fc\u30b3\u30fc\u30c9\u306e\u63d0\u4f9b<\/li>\n\n\n\n<li>\u30ec\u30fc\u30c8\u5236\u9650\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406\u306e\u6700\u9069\u5316<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>API\u30c8\u30fc\u30af\u30f3\u8a8d\u8a3c<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30c8\u30fc\u30af\u30f3\u306e\u6709\u52b9\u671f\u9650\u7ba1\u7406<\/li>\n\n\n\n<li>\u9069\u5207\u306a\u30b9\u30b3\u30fc\u30d7\u8a2d\u5b9a<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30a2\u306a\u30c8\u30fc\u30af\u30f3\u4fdd\u5b58<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-15\">\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56<\/h2>\n\n\n\n<p>Laravel\u306e\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u3092\u672c\u756a\u74b0\u5883\u3067\u904b\u7528\u3059\u308b\u969b\u306b\u5fc5\u8981\u306a\u3001\u91cd\u8981\u306a\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-16\">\u30af\u30ed\u30b9\u30b5\u30a4\u30c8\u30ea\u30af\u30a8\u30b9\u30c8\u30d5\u30a9\u30fc\u30b8\u30a7\u30ea\u5bfe\u7b56<\/h3>\n\n\n\n<p>CSRF\u306f\u3001\u30e6\u30fc\u30b6\u30fc\u304c\u610f\u56f3\u3057\u306a\u3044\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u9001\u4fe1\u3055\u305b\u3089\u308c\u308b\u653b\u6483\u3067\u3059\u3002Laravel\u3067\u306f\u4ee5\u4e0b\u306e\u65b9\u6cd5\u3067\u5bfe\u7b56\u3092\u5b9f\u88c5\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>CSRF\u4fdd\u8b77\u306e\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Kernel.php\nprotected $middlewareGroups = [\n    'web' =&gt; [\n        \\App\\Http\\Middleware\\EncryptCookies::class,\n        \\Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse::class,\n        \\Illuminate\\Session\\Middleware\\StartSession::class,\n        \\Illuminate\\View\\Middleware\\ShareErrorsFromSession::class,\n        \\App\\Http\\Middleware\\VerifyCsrfToken::class,  \/\/ CSRF\u4fdd\u8b77\n        \\Illuminate\\Routing\\Middleware\\SubstituteBindings::class,\n    ],\n];<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30c8\u30fc\u30af\u30f3\u306e\u691c\u8a3c\u3068\u4f8b\u5916\u51e6\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Middleware\/VerifyCsrfToken.php\nnamespace App\\Http\\Middleware;\n\nuse Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken as Middleware;\n\nclass VerifyCsrfToken extends Middleware\n{\n    protected $except = [\n        \/\/ CSRF\u30c8\u30fc\u30af\u30f3\u691c\u8a3c\u3092\u9664\u5916\u3059\u308b\u30d1\u30b9\n        'webhook\/*',\n        'api\/*'\n    ];\n\n    protected function tokensMatch($request)\n    {\n        $token = $this-&gt;getTokenFromRequest($request);\n        $valid = is_string($request-&gt;session()-&gt;token()) &amp;&amp;\n                is_string($token) &amp;&amp;\n                hash_equals($request-&gt;session()-&gt;token(), $token);\n\n        if (!$valid) {\n            \\Log::warning('CSRF token mismatch', [\n                'ip' =&gt; $request-&gt;ip(),\n                'user_agent' =&gt; $request-&gt;userAgent(),\n                'path' =&gt; $request-&gt;path()\n            ]);\n        }\n\n        return $valid;\n    }\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30d5\u30a9\u30fc\u30e0\u3067\u306eCSRF\u30c8\u30fc\u30af\u30f3\u4f7f\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ resources\/views\/auth\/login.blade.php\n&lt;form method=\"POST\" action=\"{{ route('login') }}\"&gt;\n    @csrf  {{-- CSRF\u30c8\u30fc\u30af\u30f3\u306e\u81ea\u52d5\u751f\u6210 --}}\n    \/\/ \u30d5\u30a9\u30fc\u30e0\u306e\u5185\u5bb9\n&lt;\/form&gt;<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-17\">\u30d6\u30eb\u30fc\u30c8\u30d5\u30a9\u30fc\u30b9\u653b\u6483\u3078\u306e\u5bfe\u51e6\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u30d1\u30b9\u30ef\u30fc\u30c9\u7dcf\u5f53\u305f\u308a\u653b\u6483\u3092\u9632\u3050\u305f\u3081\u306b\u3001\u4ee5\u4e0b\u306e\u5bfe\u7b56\u3092\u5b9f\u88c5\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ec\u30fc\u30c8\u5236\u9650\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Middleware\/ThrottleLogins.php\nnamespace App\\Http\\Middleware;\n\nuse Illuminate\\Auth\\Events\\Lockout;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Str;\n\nclass ThrottleLogins\n{\n    protected $maxAttempts = 5;\n    protected $decayMinutes = 10;\n\n    public function handle($request, \\Closure $next)\n    {\n        $key = $this-&gt;throttleKey($request);\n        $limiter = app(RateLimiter::class);\n\n        if ($limiter-&gt;tooManyAttempts($key, $this-&gt;maxAttempts)) {\n            event(new Lockout($request));\n\n            $seconds = $limiter-&gt;availableIn($key);\n\n            return response()-&gt;json([\n                'message' =&gt; __('auth.throttle', [\n                    'seconds' =&gt; $seconds,\n                    'minutes' =&gt; ceil($seconds \/ 60)\n                ]),\n                'remaining_seconds' =&gt; $seconds\n            ], 429);\n        }\n\n        $limiter-&gt;hit($key, $this-&gt;decayMinutes * 60);\n\n        $response = $next($request);\n\n        if ($response-&gt;getStatusCode() === 200) {\n            $limiter-&gt;clear($key);\n        }\n\n        return $response-&gt;header('X-RateLimit-Limit', $this-&gt;maxAttempts)\n                       -&gt;header('X-RateLimit-Remaining', $limiter-&gt;retriesLeft($key, $this-&gt;maxAttempts));\n    }\n\n    protected function throttleKey(Request $request)\n    {\n        return Str::lower($request-&gt;input('email')) . '|' . $request-&gt;ip();\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30ed\u30b0\u30a4\u30f3\u8a66\u884c\u306e\u76e3\u8996<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Providers\/EventServiceProvider.php\nprotected $listen = [\n    'Illuminate\\Auth\\Events\\Failed' =&gt; [\n        'App\\Listeners\\LogFailedLogin',\n    ],\n];\n\n\/\/ app\/Listeners\/LogFailedLogin.php\nnamespace App\\Listeners;\n\nuse Illuminate\\Auth\\Events\\Failed;\nuse Illuminate\\Support\\Facades\\Log;\n\nclass LogFailedLogin\n{\n    public function handle(Failed $event)\n    {\n        Log::warning('\u30ed\u30b0\u30a4\u30f3\u5931\u6557', [\n            'email' =&gt; $event-&gt;credentials['email'],\n            'ip' =&gt; request()-&gt;ip(),\n            'user_agent' =&gt; request()-&gt;userAgent()\n        ]);\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-18\">\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<p>\u30bb\u30ad\u30e5\u30a2\u306a\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406\u306e\u305f\u3081\u306e\u5b9f\u88c5\u65b9\u6cd5\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30bb\u30c3\u30b7\u30e7\u30f3\u8a2d\u5b9a\u306e\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ config\/session.php\nreturn [\n    'driver' =&gt; env('SESSION_DRIVER', 'redis'),\n    'lifetime' =&gt; env('SESSION_LIFETIME', 120),\n    'expire_on_close' =&gt; true,\n    'encrypt' =&gt; true,\n    'secure' =&gt; env('SESSION_SECURE_COOKIE', true),\n    'same_site' =&gt; 'lax',\n    'http_only' =&gt; true,\n];<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30bb\u30c3\u30b7\u30e7\u30f3\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Middleware\/SessionSecurity.php\nnamespace App\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Support\\Str;\n\nclass SessionSecurity\n{\n    public function handle($request, Closure $next)\n    {\n        if ($request-&gt;user()) {\n            \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3ID\u306e\u518d\u751f\u6210\uff08\u30bb\u30c3\u30b7\u30e7\u30f3\u30d5\u30a3\u30af\u30bb\u30fc\u30b7\u30e7\u30f3\u5bfe\u7b56\uff09\n            if (!$request-&gt;session()-&gt;has('_regenerated')) {\n                $request-&gt;session()-&gt;regenerate();\n                $request-&gt;session()-&gt;put('_regenerated', true);\n            }\n\n            \/\/ IP\u30a2\u30c9\u30ec\u30b9\u306e\u5909\u66f4\u691c\u77e5\n            if ($request-&gt;session()-&gt;has('_client_ip')) {\n                if ($request-&gt;session()-&gt;get('_client_ip') !== $request-&gt;ip()) {\n                    auth()-&gt;logout();\n                    $request-&gt;session()-&gt;invalidate();\n                    return redirect()-&gt;route('login')\n                        -&gt;with('error', '\u30bb\u30c3\u30b7\u30e7\u30f3\u304c\u7121\u52b9\u306b\u306a\u308a\u307e\u3057\u305f\u3002\u518d\u5ea6\u30ed\u30b0\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044\u3002');\n                }\n            } else {\n                $request-&gt;session()-&gt;put('_client_ip', $request-&gt;ip());\n            }\n\n            \/\/ User-Agent\u306e\u5909\u66f4\u691c\u77e5\n            if ($request-&gt;session()-&gt;has('_user_agent')) {\n                if ($request-&gt;session()-&gt;get('_user_agent') !== $request-&gt;userAgent()) {\n                    auth()-&gt;logout();\n                    $request-&gt;session()-&gt;invalidate();\n                    return redirect()-&gt;route('login')\n                        -&gt;with('error', '\u30bb\u30c3\u30b7\u30e7\u30f3\u304c\u7121\u52b9\u306b\u306a\u308a\u307e\u3057\u305f\u3002\u518d\u5ea6\u30ed\u30b0\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044\u3002');\n                }\n            } else {\n                $request-&gt;session()-&gt;put('_user_agent', $request-&gt;userAgent());\n            }\n\n            \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u6709\u52b9\u671f\u9650\u306e\u66f4\u65b0\n            $request-&gt;session()-&gt;put('_last_activity', time());\n        }\n\n        return $next($request);\n    }\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30bb\u30c3\u30b7\u30e7\u30f3\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Console\/Commands\/CleanupExpiredSessions.php\nnamespace App\\Console\\Commands;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Facades\\DB;\n\nclass CleanupExpiredSessions extends Command\n{\n    protected $signature = 'session:cleanup';\n    protected $description = '\u671f\u9650\u5207\u308c\u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u524a\u9664';\n\n    public function handle()\n    {\n        $lifetime = config('session.lifetime') * 60;\n\n        DB::table('sessions')\n            -&gt;where('last_activity', '&lt;', time() - $lifetime)\n            -&gt;delete();\n\n        $this-&gt;info('\u671f\u9650\u5207\u308c\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u524a\u9664\u3057\u307e\u3057\u305f\u3002');\n    }\n}<\/pre>\n\n\n\n<p>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5b9f\u88c5\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u8a8d\u8a3c\u5168\u822c<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u6700\u5c0f\u9577\u3068\u8907\u96d1\u6027\u306e\u8981\u4ef6\u8a2d\u5b9a<\/li>\n\n\n\n<li>\u591a\u8981\u7d20\u8a8d\u8a3c\u306e\u63a8\u5968<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30a2\u306a\u30d1\u30b9\u30ef\u30fc\u30c9\u30ea\u30bb\u30c3\u30c8\u30d5\u30ed\u30fc<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9069\u5207\u306a\u30bb\u30c3\u30b7\u30e7\u30f3\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8<\/li>\n\n\n\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u30d5\u30a3\u30af\u30bb\u30fc\u30b7\u30e7\u30f3\u5bfe\u7b56<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30a2\u306a\u30af\u30c3\u30ad\u30fc\u8a2d\u5b9a<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30a2\u30af\u30bb\u30b9\u5236\u5fa1<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9069\u5207\u306a\u8a8d\u53ef\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30ec\u30fc\u30c8\u5236\u9650\u306e\u8a2d\u5b9a<\/li>\n\n\n\n<li>\u30a8\u30e9\u30fc\u30ed\u30b0\u306e\u9069\u5207\u306a\u7ba1\u7406<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-19\">\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u3068\u30c7\u30d0\u30c3\u30b0<\/h2>\n\n\n\n<p>\u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\u306e\u958b\u767a\u30fb\u904b\u7528\u6642\u306b\u767a\u751f\u3057\u3084\u3059\u3044\u554f\u984c\u3068\u305d\u306e\u89e3\u6c7a\u65b9\u6cd5\u306b\u3064\u3044\u3066\u3001\u5b9f\u8df5\u7684\u306a\u8996\u70b9\u304b\u3089\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-20\">\u3088\u304f\u3042\u308b\u30a8\u30e9\u30fc\u3068\u305d\u306e\u89e3\u6c7a\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u8a8d\u8a3c\u304c\u5e38\u306b\u5931\u6557\u3059\u308b\u554f\u984c<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u554f\u984c\u306e\u5207\u308a\u5206\u3051\u3068\u89e3\u6c7a\u65b9\u6cd5\n\n\/\/ 1. \u30cf\u30c3\u30b7\u30e5\u30a2\u30eb\u30b4\u30ea\u30ba\u30e0\u306e\u78ba\u8a8d\n\/\/ config\/hashing.php\nreturn [\n    'driver' =&gt; 'bcrypt',\n    'bcrypt' =&gt; [\n        'rounds' =&gt; env('BCRYPT_ROUNDS', 10),\n    ],\n];\n\n\/\/ 2. \u30d1\u30b9\u30ef\u30fc\u30c9\u30cf\u30c3\u30b7\u30e5\u5316\u306e\u691c\u8a3c\n$user = User::find(1);\nif (Hash::check('\u5165\u529b\u3055\u308c\u305f\u30d1\u30b9\u30ef\u30fc\u30c9', $user-&gt;password)) {\n    Log::info('\u30d1\u30b9\u30ef\u30fc\u30c9\u30cf\u30c3\u30b7\u30e5\u306f\u6b63\u3057\u304f\u52d5\u4f5c\u3057\u3066\u3044\u307e\u3059');\n}\n\n\/\/ 3. \u30bb\u30c3\u30b7\u30e7\u30f3\u8a2d\u5b9a\u306e\u78ba\u8a8d\n\/\/ config\/session.php\nreturn [\n    'driver' =&gt; env('SESSION_DRIVER', 'file'),\n    'lifetime' =&gt; env('SESSION_LIFETIME', 120),\n    'encrypt' =&gt; true,\n];<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30c8\u30fc\u30af\u30f3\u30df\u30b9\u30de\u30c3\u30c1\u30a8\u30e9\u30fc\u306e\u5bfe\u51e6<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Middleware\/VerifyCsrfToken.php\nnamespace App\\Http\\Middleware;\n\nuse Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken as Middleware;\nuse Illuminate\\Session\\TokenMismatchException;\n\nclass VerifyCsrfToken extends Middleware\n{\n    protected function handleTokenMismatch($request)\n    {\n        \/\/ \u30c8\u30fc\u30af\u30f3\u30df\u30b9\u30de\u30c3\u30c1\u6642\u306e\u30ed\u30b0\u8a18\u9332\n        Log::warning('CSRF\u30c8\u30fc\u30af\u30f3\u30df\u30b9\u30de\u30c3\u30c1', [\n            'url' =&gt; $request-&gt;fullUrl(),\n            'method' =&gt; $request-&gt;method(),\n            'ip' =&gt; $request-&gt;ip(),\n            'user_agent' =&gt; $request-&gt;userAgent(),\n            'session_id' =&gt; $request-&gt;session()-&gt;getId()\n        ]);\n\n        \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u518d\u751f\u6210\n        $request-&gt;session()-&gt;regenerateToken();\n\n        return redirect()-&gt;back()\n            -&gt;withInput($request-&gt;except('password'))\n            -&gt;withErrors(['token' =&gt; '\u30bb\u30c3\u30b7\u30e7\u30f3\u304c\u671f\u9650\u5207\u308c\u3067\u3059\u3002\u3082\u3046\u4e00\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002']);\n    }\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30bb\u30c3\u30b7\u30e7\u30f3\u95a2\u9023\u306e\u554f\u984c\u89e3\u6c7a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Controllers\/Auth\/LoginController.php\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Auth;\n\nclass LoginController extends Controller\n{\n    protected function authenticated(Request $request, $user)\n    {\n        \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u30c7\u30d0\u30c3\u30b0\u60c5\u5831\u3092\u8a18\u9332\n        Log::debug('\u8a8d\u8a3c\u6210\u529f', [\n            'user_id' =&gt; $user-&gt;id,\n            'session_id' =&gt; $request-&gt;session()-&gt;getId(),\n            'ip' =&gt; $request-&gt;ip(),\n            'user_agent' =&gt; $request-&gt;userAgent()\n        ]);\n\n        \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u6b63\u5e38\u6027\u30c1\u30a7\u30c3\u30af\n        if (!$request-&gt;session()-&gt;has('_token')) {\n            Log::error('\u30bb\u30c3\u30b7\u30e7\u30f3\u30c8\u30fc\u30af\u30f3\u304c\u5b58\u5728\u3057\u307e\u305b\u3093');\n            auth()-&gt;logout();\n            return redirect()-&gt;route('login')\n                -&gt;withErrors(['email' =&gt; '\u30bb\u30c3\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002']);\n        }\n\n        return redirect()-&gt;intended($this-&gt;redirectPath());\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-21\">\u30ed\u30b0\u30a4\u30f3\u51e6\u7406\u306e\u52d5\u4f5c\u78ba\u8a8d\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30c7\u30d0\u30c3\u30b0\u30e2\u30fc\u30c9\u3067\u306e\u78ba\u8a8d<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Providers\/AppServiceProvider.php\npublic function boot()\n{\n    if (config('app.debug')) {\n        DB::listen(function ($query) {\n            Log::info(\n                $query-&gt;sql,\n                [\n                    'bindings' =&gt; $query-&gt;bindings,\n                    'time' =&gt; $query-&gt;time\n                ]\n            );\n        });\n\n        \/\/ \u8a8d\u8a3c\u30a4\u30d9\u30f3\u30c8\u306e\u76e3\u8996\n        Event::listen('Illuminate\\Auth\\Events\\Login', function ($event) {\n            Log::info('\u30ed\u30b0\u30a4\u30f3\u6210\u529f', [\n                'user' =&gt; $event-&gt;user-&gt;toArray(),\n                'remember' =&gt; $event-&gt;remember\n            ]);\n        });\n\n        Event::listen('Illuminate\\Auth\\Events\\Failed', function ($event) {\n            Log::warning('\u30ed\u30b0\u30a4\u30f3\u5931\u6557', [\n                'credentials' =&gt; $event-&gt;credentials,\n                'guard' =&gt; $event-&gt;guard\n            ]);\n        });\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30c6\u30b9\u30c8\u7528\u306e\u30d8\u30eb\u30d1\u30fc\u95a2\u6570<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ tests\/TestCase.php\nnamespace Tests;\n\nuse Illuminate\\Foundation\\Testing\\TestCase as BaseTestCase;\nuse App\\Models\\User;\n\nabstract class TestCase extends BaseTestCase\n{\n    use CreatesApplication;\n\n    protected function createUserAndLogin($attributes = [])\n    {\n        $user = User::factory()-&gt;create($attributes);\n        $this-&gt;actingAs($user);\n        return $user;\n    }\n\n    protected function assertAuthenticatedAs($user)\n    {\n        $this-&gt;assertTrue(auth()-&gt;check());\n        $this-&gt;assertTrue(auth()-&gt;user()-&gt;is($user));\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-22\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u30dd\u30a4\u30f3\u30c8<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30af\u30a8\u30ea\u306e\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Models\/User.php\npublic function scopeWithLoginInfo($query)\n{\n    return $query-&gt;select([\n        'id', 'email', 'password', \n        'name', 'remember_token'\n    ])-&gt;with(['roles:id,name']);\n}\n\n\/\/ app\/Http\/Controllers\/Auth\/LoginController.php\nprotected function attemptLogin(Request $request)\n{\n    $credentials = $request-&gt;only('email', 'password');\n    $remember = $request-&gt;filled('remember');\n\n    \/\/ \u5fc5\u8981\u306a\u60c5\u5831\u306e\u307f\u3092\u53d6\u5f97\n    $user = User::withLoginInfo()\n        -&gt;where('email', $credentials['email'])\n        -&gt;first();\n\n    if (!$user) {\n        return false;\n    }\n\n    if (Hash::check($credentials['password'], $user-&gt;password)) {\n        $this-&gt;guard()-&gt;login($user, $remember);\n        return true;\n    }\n\n    return false;\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u6d3b\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Models\/User.php\npublic function getRolesAttribute()\n{\n    return Cache::remember(\n        \"user.{$this-&gt;id}.roles\",\n        now()-&gt;addMinutes(60),\n        fn() =&gt; $this-&gt;roles()-&gt;get()\n    );\n}<\/pre>\n\n\n\n<p>\u4ee3\u8868\u7684\u306a\u30c8\u30e9\u30d6\u30eb\u3068\u89e3\u6c7a\u65b9\u6cd5\u306e\u307e\u3068\u3081\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u8a8d\u8a3c\u5931\u6557\u306e\u4e00\u822c\u7684\u306a\u539f\u56e0<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u30c9\u30e9\u30a4\u30d0\u306e\u8a2d\u5b9a\u30df\u30b9<\/li>\n\n\n\n<li>\u30d1\u30b9\u30ef\u30fc\u30c9\u30cf\u30c3\u30b7\u30e5\u306e\u4e0d\u4e00\u81f4<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u63a5\u7d9a\u306e\u554f\u984c<\/li>\n\n\n\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u6574\u5408\u6027\u306e\u554f\u984c<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u89e3\u6c7a\u306e\u30a2\u30d7\u30ed\u30fc\u30c1<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30ed\u30b0\u306e\u8a73\u7d30\u306a\u78ba\u8a8d<\/li>\n\n\n\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u72b6\u614b\u306e\u691c\u8a3c<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30af\u30a8\u30ea\u306e\u78ba\u8a8d<\/li>\n\n\n\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u30af\u30ea\u30a2<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u4e88\u9632\u7684\u306a\u5bfe\u7b56<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9069\u5207\u306a\u30ed\u30b0\u8a2d\u5b9a<\/li>\n\n\n\n<li>\u5b9a\u671f\u7684\u306a\u30bb\u30c3\u30b7\u30e7\u30f3\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7<\/li>\n\n\n\n<li>\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>\u76e3\u8996\u30b7\u30b9\u30c6\u30e0\u306e\u5c0e\u5165<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Warning: Undefined array key &#8220;is_admin&#8221; in \/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/ &#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33,12],"tags":[],"class_list":{"0":"post-3279","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-php-laravel","7":"category-php","8":"nothumb"},"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/3279","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3279"}],"version-history":[{"count":2,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/3279\/revisions"}],"predecessor-version":[{"id":3281,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/3279\/revisions\/3281"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3279"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3279"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3279"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}