{"id":2700,"date":"2025-03-24T08:46:45","date_gmt":"2025-03-23T23:46:45","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=2700"},"modified":"2025-03-24T08:47:15","modified_gmt":"2025-03-23T23:47:15","slug":"%e3%80%90%e4%bf%9d%e5%ad%98%e7%89%88%e3%80%91laravel-permission%e3%81%ae%e5%ae%8c%e5%85%a8%e3%82%ac%e3%82%a4%e3%83%89%ef%bc%9a5%e3%81%a4%e3%81%ae%e5%ae%9f%e8%b7%b5%e7%9a%84%e3%81%aa%e5%ae%9f%e8%a3%85","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=2700","title":{"rendered":"\u3010\u4fdd\u5b58\u7248\u3011Laravel Permission\u306e\u5b8c\u5168\u30ac\u30a4\u30c9\uff1a5\u3064\u306e\u5b9f\u8df5\u7684\u306a\u5b9f\u88c5\u65b9\u6cd5\u30683\u3064\u306e\u91cd\u8981\u306a\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0"},"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 Permission \u3068\u306f\uff1a\u6a5f\u80fd\u3068\u91cd\u8981\u6027<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">Laravel Permission \u304c\u89e3\u6c7a\u3059\u308b 3 \u3064\u306e\u8ab2\u984c<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-2\">Spatie\/laravel-permission \u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u7279\u5fb4<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-3\">Laravel Permission \u306e\u57fa\u672c\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u624b\u9806<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-4\">\u30b3\u30f3\u30dd\u30fc\u30b6\u30fc\u3092\u4f7f\u7528\u3057\u305f\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-5\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u884c\u624b\u9806<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-6\">\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-7\">\u6a29\u9650\u3068\u30ed\u30fc\u30eb\u306e\u5b9f\u88c5\u65b9\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-8\">\u57fa\u672c\u7684\u306a\u6a29\u9650\u306e\u4f5c\u6210\u3068\u7ba1\u7406<\/a>      <\/li>      <li>        <a href=\"#i-9\">\u30ed\u30fc\u30eb\u306e\u5b9a\u7fa9\u3068\u30e6\u30fc\u30b6\u30fc\u3078\u306e\u6a29\u5229\u4ed8\u4e0e<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-10\">\u6a29\u9650\u3068\u30ed\u30fc\u30eb\u306e\u968e\u5c64\u69cb\u9020\u306e\u8a2d\u8a08<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-11\">\u5b9f\u8df5\u7684\u306a\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f35\u9078<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-12\">\u7ba1\u7406\u8005\u753b\u9762\u3067\u306e\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0<\/a>      <\/li>      <li>        <a href=\"#i-13\">\u8907\u6570\u30c1\u30fc\u30e0\u5bfe\u5fdc\u306e\u6a29\u9650\u8a2d\u8a08<\/a>      <\/li>      <li>        <a href=\"#i-14\">\u52d5\u7684\u306a\u6a29\u9650\u4ed8\u4e0e\u30b7\u30b9\u30c6\u30e0<\/a>      <\/li>      <li>        <a href=\"#i-15\">API\u3067\u306e\u6a29\u9650\u7ba1\u7406\u306e\u5b9f\u88c5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-16\">\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u6d3b\u7528\u3057\u305f\u9ad8\u901f\u306a\u6a29\u9650\u30c1\u30a7\u30c3\u30af<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-17\">\u91cd\u8981\u306a\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b03\u9078<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-18\">\u6a29\u9650\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u66f4\u65b0\u554f\u984c\u3068\u89e3\u6c7a\u7b56<\/a>      <\/li>      <li>        <a href=\"#i-19\">N+1\u554f\u984c\u306e\u56de\u907f\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-20\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-21\">Laravel\u6a29\u9650\u306e\u5fdc\u7528\u3068\u767a\u5c55<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-22\">\u30c6\u30b9\u30c8\u74b0\u5883\u3067\u306e\u6a29\u9650\u7ba1\u7406\u306e\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-23\">\u30ab\u30b9\u30bf\u30e0\u30ac\u30fc\u30c9\u3068\u306e\u9023\u643a\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-24\">\u30de\u30eb\u30c1\u30c6\u30ca\u30f3\u30c8\u3067\u306e\u6a29\u9650\u8a2d\u8a08\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/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 Permission \u3068\u306f\uff1a\u6a5f\u80fd\u3068\u91cd\u8981\u6027<\/h2>\n\n\n\n<p>Web\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u304a\u3044\u3066\u3001\u9069\u5207\u306a\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u306e\u5b9f\u88c5\u306f\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3068\u904b\u7528\u52b9\u7387\u306e\u4e21\u9762\u3067\u6975\u3081\u3066\u91cd\u8981\u3067\u3059\u3002Laravel Permission\u306f\u3001\u3053\u306e\u6a29\u9650\u7ba1\u7406\u3092\u52b9\u7387\u7684\u304b\u3064\u67d4\u8edf\u306b\u5b9f\u88c5\u3059\u308b\u305f\u3081\u306e\u30d1\u30c3\u30b1\u30fc\u30b8\u3068\u3057\u3066\u3001\u591a\u304f\u306e\u958b\u767a\u73fe\u5834\u3067\u63a1\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-1\">Laravel Permission \u304c\u89e3\u6c7a\u3059\u308b 3 \u3064\u306e\u8ab2\u984c<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u6a29\u9650\u7ba1\u7406\u306e\u8907\u96d1\u6027\u3078\u306e\u5bfe\u5fdc<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5f93\u6765\u306e\u6a29\u9650\u7ba1\u7406\u3067\u306f\u3001\u500b\u5225\u306e\u6a29\u9650\u30c1\u30a7\u30c3\u30af\u30ed\u30b8\u30c3\u30af\u304c\u6563\u5728\u3057\u3001\u30b3\u30fc\u30c9\u306e\u4fdd\u5b88\u6027\u304c\u4f4e\u4e0b<\/li>\n\n\n\n<li>\u30ab\u30b9\u30bf\u30e0\u30ed\u30b8\u30c3\u30af\u306e\u5b9f\u88c5\u306b\u3088\u308a\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30db\u30fc\u30eb\u306e\u30ea\u30b9\u30af\u304c\u5897\u5927<\/li>\n\n\n\n<li>\u30c1\u30fc\u30e0\u9593\u3067\u306e\u6a29\u9650\u5b9f\u88c5\u306e\u4e00\u8cab\u6027\u304c\u7dad\u6301\u56f0\u96e3<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b9\u30b1\u30fc\u30e9\u30d3\u30ea\u30c6\u30a3\u306e\u78ba\u4fdd<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30e6\u30fc\u30b6\u30fc\u6570\u3084\u6a29\u9650\u6570\u306e\u5897\u52a0\u306b\u4f34\u3046\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u4f4e\u4e0b<\/li>\n\n\n\n<li>\u6a29\u9650\u30c1\u30a7\u30c3\u30af\u51e6\u7406\u306e\u983b\u767a\u306b\u3088\u308b\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8ca0\u8377\u306e\u5897\u5927<\/li>\n\n\n\n<li>\u8907\u96d1\u306a\u6a29\u9650\u968e\u5c64\u69cb\u9020\u306e\u7ba1\u7406\u306b\u304a\u3051\u308b\u8ab2\u984c<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u958b\u767a\u52b9\u7387\u3068\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6a29\u9650\u30ed\u30b8\u30c3\u30af\u306e\u91cd\u8907\u5b9f\u88c5\u306b\u3088\u308b\u958b\u767a\u5de5\u6570\u306e\u5897\u52a0<\/li>\n\n\n\n<li>\u6a29\u9650\u8a2d\u5b9a\u306e\u5909\u66f4\u306b\u4f34\u3046\u5e83\u7bc4\u306a\u4fee\u6b63\u306e\u5fc5\u8981\u6027<\/li>\n\n\n\n<li>\u30c6\u30b9\u30c8\u5de5\u6570\u306e\u5897\u5927\u3068\u54c1\u8cea\u62c5\u4fdd\u306e\u96e3\u3057\u3055<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-2\">Spatie\/laravel-permission \u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u7279\u5fb4<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u7d71\u5408\u7684\u306a\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0<\/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=\"\">\/\/ \u76f4\u611f\u7684\u306a\u6a29\u9650\u30c1\u30a7\u30c3\u30af\nif ($user-&gt;can('edit articles')) {\n    \/\/ \u8a18\u4e8b\u7de8\u96c6\u51e6\u7406\n}\n\n\/\/ \u30ed\u30fc\u30eb\u30d9\u30fc\u30b9\u306e\u6a29\u9650\u7ba1\u7406\nif ($user-&gt;hasRole('editor')) {\n    \/\/ \u30a8\u30c7\u30a3\u30bf\u30fc\u5411\u3051\u51e6\u7406\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u9ad8\u5ea6\u306a\u6a5f\u80fd\u30bb\u30c3\u30c8<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30ed\u30fc\u30eb\u3068\u6a29\u9650\u306e\u67d4\u8edf\u306a\u7d44\u307f\u5408\u308f\u305b<\/li>\n\n\n\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u30b7\u30b9\u30c6\u30e0\u306e\u7d44\u307f\u8fbc\u307f\u30b5\u30dd\u30fc\u30c8<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30af\u30a8\u30ea\u306e\u6700\u9069\u5316\u6a5f\u80fd<\/li>\n\n\n\n<li>\u968e\u5c64\u7684\u306a\u6a29\u9650\u69cb\u9020\u306e\u5b9f\u88c5\u30b5\u30dd\u30fc\u30c8<\/li>\n<\/ul>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>Laravel\u6a19\u6e96\u6a5f\u80fd\u3068\u306e\u512a\u308c\u305f\u7d71\u5408\u6027<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u3092\u4f7f\u7528\u3057\u305f\u7c21\u6f54\u306a\u5b9f\u88c5<\/li>\n<\/ul>\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=\"\">Route::middleware(['permission:edit articles'])-&gt;group(function () {\n    Route::get('\/articles\/{article}\/edit', 'ArticleController@edit');\n});<\/pre>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>\u62e1\u5f35\u6027\u3068\u4fdd\u5b88\u6027\u306e\u5411\u4e0a<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30e2\u30b8\u30e5\u30fc\u30eb\u5316\u3055\u308c\u305f\u6a29\u9650\u7ba1\u7406\u69cb\u9020<\/li>\n\n\n\n<li>\u6a19\u6e96\u5316\u3055\u308c\u305fAPI\u63d0\u4f9b<\/li>\n\n\n\n<li>\u5305\u62ec\u7684\u306a\u30c6\u30b9\u30c8\u30b5\u30dd\u30fc\u30c8<\/li>\n\n\n\n<li>\u30a2\u30af\u30c6\u30a3\u30d6\u306a\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u30b5\u30dd\u30fc\u30c8<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u306e\u30d1\u30c3\u30b1\u30fc\u30b8\u3092\u63a1\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u958b\u767a\u8005\u306f\u4ee5\u4e0b\u306e\u30e1\u30ea\u30c3\u30c8\u3092\u5f97\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6a29\u9650\u7ba1\u7406\u6a5f\u80fd\u306e\u8fc5\u901f\u306a\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30ea\u30b9\u30af\u306e\u4f4e\u6e1b<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u306e\u4fdd\u5b88\u6027\u5411\u4e0a<\/li>\n\n\n\n<li>\u958b\u767a\u52b9\u7387\u306e\u6700\u9069\u5316<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-3\">Laravel Permission \u306e\u57fa\u672c\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u624b\u9806<\/h2>\n\n\n\n<p>Laravel Permission\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u306f\u3001\u5927\u304d\u304f\u5206\u3051\u30663\u3064\u306e\u30b9\u30c6\u30c3\u30d7\u3067\u5b9f\u65bd\u3057\u307e\u3059\u3002\u3053\u308c\u3089\u306e\u624b\u9806\u3092\u6b63\u78ba\u306b\u884c\u3046\u3053\u3068\u3067\u3001\u5805\u7262\u306a\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u306e\u57fa\u76e4\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-4\">\u30b3\u30f3\u30dd\u30fc\u30b6\u30fc\u3092\u4f7f\u7528\u3057\u305f\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb<\/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=\"\"># Spatie\/laravel-permission\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\ncomposer require spatie\/laravel-permission\n\n# \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u30af\u30ea\u30a2\nphp artisan optimize:clear<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0\u306e\u767b\u9332<\/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\/app.php \u306b\u4ee5\u4e0b\u3092\u8ffd\u52a0\n'providers' =&gt; [\n    \/\/ ...\n    Spatie\\Permission\\PermissionServiceProvider::class,\n],<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u521d\u671f\u8a2d\u5b9a\u306e\u78ba\u8a8d<\/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\/auth.php \u3067\u30c7\u30d5\u30a9\u30eb\u30c8\u30ac\u30fc\u30c9\u306e\u78ba\u8a8d\n'defaults' =&gt; [\n    'guard' =&gt; 'web',\n    'passwords' =&gt; 'users',\n],<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u884c\u624b\u9806<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u306e\u6e96\u5099<\/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=\"\"># \u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3068\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u516c\u958b\nphp artisan vendor:publish --provider=\"Spatie\\Permission\\PermissionServiceProvider\"\n\n# \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u884c\nphp artisan migrate<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u4f5c\u6210\u3055\u308c\u308b\u30c6\u30fc\u30d6\u30eb\u69cb\u9020<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>roles<\/code>: \u30ed\u30fc\u30eb\u306e\u57fa\u672c\u60c5\u5831\u3092\u7ba1\u7406<\/li>\n\n\n\n<li><code>id<\/code>: \u30ed\u30fc\u30eb\u306e\u4e00\u610f\u8b58\u5225\u5b50<\/li>\n\n\n\n<li><code>name<\/code>: \u30ed\u30fc\u30eb\u540d<\/li>\n\n\n\n<li><code>guard_name<\/code>: \u4f7f\u7528\u3059\u308b\u30ac\u30fc\u30c9\u540d<\/li>\n\n\n\n<li><code>timestamps<\/code>: \u4f5c\u6210\u30fb\u66f4\u65b0\u65e5\u6642<\/li>\n\n\n\n<li><code>permissions<\/code>: \u6a29\u9650\u306e\u57fa\u672c\u60c5\u5831\u3092\u7ba1\u7406<\/li>\n\n\n\n<li><code>id<\/code>: \u6a29\u9650\u306e\u4e00\u610f\u8b58\u5225\u5b50<\/li>\n\n\n\n<li><code>name<\/code>: \u6a29\u9650\u540d<\/li>\n\n\n\n<li><code>guard_name<\/code>: \u4f7f\u7528\u3059\u308b\u30ac\u30fc\u30c9\u540d<\/li>\n\n\n\n<li><code>timestamps<\/code>: \u4f5c\u6210\u30fb\u66f4\u65b0\u65e5\u6642<\/li>\n\n\n\n<li>\u4e2d\u9593\u30c6\u30fc\u30d6\u30eb\u7fa4<\/li>\n\n\n\n<li><code>model_has_roles<\/code>: \u30e2\u30c7\u30eb\u3068\u30ed\u30fc\u30eb\u306e\u95a2\u9023\u4ed8\u3051<\/li>\n\n\n\n<li><code>model_has_permissions<\/code>: \u30e2\u30c7\u30eb\u3068\u6a29\u9650\u306e\u95a2\u9023\u4ed8\u3051<\/li>\n\n\n\n<li><code>role_has_permissions<\/code>: \u30ed\u30fc\u30eb\u3068\u6a29\u9650\u306e\u95a2\u9023\u4ed8\u3051<\/li>\n<\/ul>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30e2\u30c7\u30eb\u306e\u8a2d\u5b9a<\/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\nuse Spatie\\Permission\\Traits\\HasRoles;\n\nclass User extends Authenticatable\n{\n    use HasRoles;  \/\/ \u30c8\u30ec\u30a4\u30c8\u3092\u8ffd\u52a0\n\n    \/\/ ...\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-6\">\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u57fa\u672c\u8a2d\u5b9a\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba<\/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\/permission.php\n\nreturn [\n    'models' =&gt; [\n        \/\/ \u30e2\u30c7\u30eb\u30af\u30e9\u30b9\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\n        'permission' =&gt; Spatie\\Permission\\Models\\Permission::class,\n        'role' =&gt; Spatie\\Permission\\Models\\Role::class,\n    ],\n\n    'table_names' =&gt; [\n        \/\/ \u30c6\u30fc\u30d6\u30eb\u540d\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\n        'roles' =&gt; 'roles',\n        'permissions' =&gt; 'permissions',\n        'model_has_permissions' =&gt; 'model_has_permissions',\n        'model_has_roles' =&gt; 'model_has_roles',\n        'role_has_permissions' =&gt; 'role_has_permissions',\n    ],\n];<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u8a2d\u5b9a<\/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\/permission.php\n\n'cache' =&gt; [\n    \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u6709\u52b9\u671f\u9650\u8a2d\u5b9a\n    'expiration_time' =&gt; \\DateInterval::createFromDateString('24 hours'),\n\n    \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u30ad\u30fc\u306e\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9\n    'key' =&gt; 'spatie.permission.cache',\n\n    \/\/ \u4f7f\u7528\u3059\u308b\u30ad\u30e3\u30c3\u30b7\u30e5\u30b9\u30c8\u30a2\n    'store' =&gt; 'default',\n],<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30ab\u30b9\u30bf\u30e0\u30ac\u30fc\u30c9\u306e\u8a2d\u5b9a<\/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\/auth.php\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        'hash' =&gt; false,\n    ],\n    \/\/ \u30ab\u30b9\u30bf\u30e0\u30ac\u30fc\u30c9\u306e\u8ffd\u52a0\n    'admin' =&gt; [\n        'driver' =&gt; 'session',\n        'provider' =&gt; 'admins',\n    ],\n],<\/pre>\n\n\n\n<p>\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u5b8c\u4e86\u5f8c\u306e\u52d5\u4f5c\u78ba\u8a8d\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=\"\">\/\/ \u30c6\u30b9\u30c8\u7528\u306e\u6a29\u9650\u3068\u30ed\u30fc\u30eb\u3092\u4f5c\u6210\nphp artisan tinker\n\n\/\/ \u6a29\u9650\u306e\u4f5c\u6210\u30c6\u30b9\u30c8\nPermission::create(['name' =&gt; 'edit articles']);\n\n\/\/ \u30ed\u30fc\u30eb\u306e\u4f5c\u6210\u30c6\u30b9\u30c8\nRole::create(['name' =&gt; 'editor']);\n\n\/\/ \u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u306a\u3051\u308c\u3070\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u6210\u529f<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-7\">\u6a29\u9650\u3068\u30ed\u30fc\u30eb\u306e\u5b9f\u88c5\u65b9\u6cd5<\/h2>\n\n\n\n<p>\u6a29\u9650\u3068\u30ed\u30fc\u30eb\u306e\u9069\u5207\u306a\u5b9f\u88c5\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3068\u4fdd\u5b88\u6027\u3092\u5927\u304d\u304f\u5de6\u53f3\u3057\u307e\u3059\u3002\u3053\u3053\u3067\u306f\u3001\u57fa\u672c\u7684\u306a\u5b9f\u88c5\u304b\u3089\u5b9f\u8df5\u7684\u306a\u30d1\u30bf\u30fc\u30f3\u307e\u3067\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-8\">\u57fa\u672c\u7684\u306a\u6a29\u9650\u306e\u4f5c\u6210\u3068\u7ba1\u7406<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u6a29\u9650\u306e\u4f5c\u6210\u3068\u7ba1\u7406\u65b9\u6cd5<\/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=\"\">use Spatie\\Permission\\Models\\Permission;\n\n\/\/ \u57fa\u672c\u7684\u306a\u6a29\u9650\u306e\u4f5c\u6210\nPermission::create(['name' =&gt; 'edit articles']);\n\n\/\/ \u8907\u6570\u306e\u6a29\u9650\u3092\u307e\u3068\u3081\u3066\u4f5c\u6210\n$permissions = [\n    'create articles',\n    'edit articles',\n    'delete articles',\n    'publish articles'\n];\n\ncollect($permissions)-&gt;each(function ($permission) {\n    Permission::create(['name' =&gt; $permission]);\n});<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30e6\u30fc\u30b6\u30fc\u3078\u306e\u6a29\u9650\u4ed8\u4e0e<\/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=\"\">\/\/ \u5358\u4e00\u306e\u6a29\u9650\u3092\u4ed8\u4e0e\n$user-&gt;givePermissionTo('edit articles');\n\n\/\/ \u8907\u6570\u306e\u6a29\u9650\u3092\u4e00\u5ea6\u306b\u4ed8\u4e0e\n$user-&gt;givePermissionTo(['edit articles', 'delete articles']);\n\n\/\/ \u7279\u5b9a\u306e\u6a29\u9650\u3092\u6301\u3064\u30e6\u30fc\u30b6\u30fc\u306e\u53d6\u5f97\n$users = User::permission('edit articles')-&gt;get();<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u6a29\u9650\u306e\u30c1\u30a7\u30c3\u30af\u3068\u691c\u8a3c<\/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=\"\">\/\/ \u6a29\u9650\u306e\u78ba\u8a8d\nif ($user-&gt;hasPermissionTo('edit articles')) {\n    \/\/ \u7de8\u96c6\u51e6\u7406\n}\n\n\/\/ \u8907\u6570\u6a29\u9650\u306e\u4e00\u62ec\u30c1\u30a7\u30c3\u30af\nif ($user-&gt;hasAllPermissions(['edit articles', 'publish articles'])) {\n    \/\/ \u4e21\u65b9\u306e\u6a29\u9650\u304c\u3042\u308b\u5834\u5408\u306e\u51e6\u7406\n}\n\n\/\/ Blade\u30c7\u30a3\u30ec\u30af\u30c6\u30a3\u30d6\u3067\u306e\u5229\u7528\n@can('edit articles')\n    &lt;a href=\"{{ route('articles.edit', $article) }}\"&gt;\u7de8\u96c6&lt;\/a&gt;\n@endcan<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-9\">\u30ed\u30fc\u30eb\u306e\u5b9a\u7fa9\u3068\u30e6\u30fc\u30b6\u30fc\u3078\u306e\u6a29\u5229\u4ed8\u4e0e<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30ed\u30fc\u30eb\u306e\u4f5c\u6210\u3068\u6a29\u9650\u306e\u95a2\u9023\u4ed8\u3051<\/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=\"\">use Spatie\\Permission\\Models\\Role;\n\n\/\/ \u30ed\u30fc\u30eb\u306e\u4f5c\u6210\n$role = Role::create(['name' =&gt; 'editor']);\n\n\/\/ \u30ed\u30fc\u30eb\u306b\u6a29\u9650\u3092\u4ed8\u4e0e\n$role-&gt;givePermissionTo([\n    'edit articles',\n    'publish articles'\n]);\n\n\/\/ \u6a29\u9650\u306e\u4e00\u62ec\u8a2d\u5b9a\uff08\u65e2\u5b58\u306e\u6a29\u9650\u3092\u4e0a\u66f8\u304d\uff09\n$role-&gt;syncPermissions([\n    'edit articles',\n    'publish articles',\n    'delete articles'\n]);<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30e6\u30fc\u30b6\u30fc\u3078\u306e\u30ed\u30fc\u30eb\u5272\u308a\u5f53\u3066<\/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=\"\">\/\/ \u5358\u4e00\u30ed\u30fc\u30eb\u306e\u5272\u308a\u5f53\u3066\n$user-&gt;assignRole('editor');\n\n\/\/ \u8907\u6570\u30ed\u30fc\u30eb\u306e\u5272\u308a\u5f53\u3066\n$user-&gt;assignRole(['writer', 'moderator']);\n\n\/\/ \u30ed\u30fc\u30eb\u306e\u540c\u671f\uff08\u65e2\u5b58\u306e\u30ed\u30fc\u30eb\u3092\u4e0a\u66f8\u304d\uff09\n$user-&gt;syncRoles(['editor']);<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30ed\u30fc\u30eb\u30d9\u30fc\u30b9\u306e\u6a29\u9650\u30c1\u30a7\u30c3\u30af<\/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=\"\">\/\/ \u30ed\u30fc\u30eb\u306e\u78ba\u8a8d\nif ($user-&gt;hasRole('editor')) {\n    \/\/ \u30a8\u30c7\u30a3\u30bf\u30fc\u5411\u3051\u306e\u51e6\u7406\n}\n\n\/\/ \u8907\u6570\u30ed\u30fc\u30eb\u306e\u78ba\u8a8d\nif ($user-&gt;hasAnyRole(['editor', 'admin'])) {\n    \/\/ \u3044\u305a\u308c\u304b\u306e\u30ed\u30fc\u30eb\u304c\u3042\u308b\u5834\u5408\u306e\u51e6\u7406\n}\n\n\/\/ \u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u3067\u306e\u5229\u7528\nRoute::group(['middleware' =&gt; ['role:editor']], function () {\n    Route::get('\/articles\/create', 'ArticleController@create');\n});<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-10\">\u6a29\u9650\u3068\u30ed\u30fc\u30eb\u306e\u968e\u5c64\u69cb\u9020\u306e\u8a2d\u8a08<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u57fa\u672c\u7684\u306a\u968e\u5c64\u69cb\u9020\u306e\u5b9f\u88c5<\/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=\"\">\/\/ \u7ba1\u7406\u8005\u968e\u5c64\u306e\u5b9a\u7fa9\n$roles = [\n    'super-admin' =&gt; [\n        'users.*',\n        'articles.*',\n        'settings.*'\n    ],\n    'content-manager' =&gt; [\n        'articles.*',\n        'comments.moderate'\n    ],\n    'editor' =&gt; [\n        'articles.create',\n        'articles.edit',\n        'articles.delete'\n    ],\n    'writer' =&gt; [\n        'articles.create',\n        'articles.edit'\n    ]\n];\n\n\/\/ \u968e\u5c64\u69cb\u9020\u306e\u5b9f\u88c5\nforeach ($roles as $roleName =&gt; $permissions) {\n    $role = Role::create(['name' =&gt; $roleName]);\n    $role-&gt;givePermissionTo($permissions);\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u6a29\u9650\u306e\u7d99\u627f\u8a2d\u8a08<\/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=\"\">\/\/ \u57fa\u672c\u6a29\u9650\u30bb\u30c3\u30c8\u306e\u5b9a\u7fa9\n$basePermissions = ['view articles', 'create articles'];\n$editorPermissions = array_merge($basePermissions, ['edit articles', 'delete articles']);\n$adminPermissions = array_merge($editorPermissions, ['publish articles', 'manage users']);\n\n\/\/ \u6a29\u9650\u306e\u7d99\u627f\u3092\u5b9f\u88c5\n$writerRole = Role::create(['name' =&gt; 'writer']);\n$writerRole-&gt;givePermissionTo($basePermissions);\n\n$editorRole = Role::create(['name' =&gt; 'editor']);\n$editorRole-&gt;givePermissionTo($editorPermissions);\n\n$adminRole = Role::create(['name' =&gt; 'admin']);\n$adminRole-&gt;givePermissionTo($adminPermissions);<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u52d5\u7684\u306a\u6a29\u9650\u7ba1\u7406<\/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=\"\">class PermissionService\n{\n    public function addPermissionsToRole(Role $role, array $permissions)\n    {\n        \/\/ \u65e2\u5b58\u306e\u6a29\u9650\u3092\u4fdd\u6301\u3057\u3064\u3064\u3001\u65b0\u3057\u3044\u6a29\u9650\u3092\u8ffd\u52a0\n        $existingPermissions = $role-&gt;permissions-&gt;pluck('name')-&gt;toArray();\n        $newPermissions = array_unique(array_merge($existingPermissions, $permissions));\n        $role-&gt;syncPermissions($newPermissions);\n    }\n\n    public function removePermissionsFromRole(Role $role, array $permissions)\n    {\n        \/\/ \u6307\u5b9a\u3055\u308c\u305f\u6a29\u9650\u306e\u307f\u3092\u524a\u9664\n        $existingPermissions = $role-&gt;permissions-&gt;pluck('name')-&gt;toArray();\n        $remainingPermissions = array_diff($existingPermissions, $permissions);\n        $role-&gt;syncPermissions($remainingPermissions);\n    }\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-11\">\u5b9f\u8df5\u7684\u306a\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f35\u9078<\/h2>\n\n\n\n<p>Laravel\u3067\u306e\u6a29\u9650\u7ba1\u7406\u306b\u304a\u3044\u3066\u3001\u5b9f\u969b\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u3088\u304f\u906d\u9047\u3059\u308b\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u3068\u305d\u306e\u89e3\u6c7a\u65b9\u6cd5\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-12\">\u7ba1\u7406\u8005\u753b\u9762\u3067\u306e\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u6a29\u9650\u7ba1\u7406\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u5b9f\u88c5<\/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=\"\">class PermissionController extends Controller\n{\n    public function index()\n    {\n        $roles = Role::with('permissions')-&gt;get();\n        $permissions = Permission::all();\n        return view('admin.permissions.index', compact('roles', 'permissions'));\n    }\n\n    public function updateRolePermissions(Request $request, Role $role)\n    {\n        $validated = $request-&gt;validate([\n            'permissions' =&gt; 'required|array',\n            'permissions.*' =&gt; 'exists:permissions,name'\n        ]);\n\n        $role-&gt;syncPermissions($validated['permissions']);\n        return back()-&gt;with('success', '\u6a29\u9650\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f');\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u7ba1\u7406\u753b\u9762\u306e\u30d3\u30e5\u30fc\u5b9f\u88c5<\/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=\"\">&lt;!-- resources\/views\/admin\/permissions\/index.blade.php --&gt;\n@foreach($roles as $role)\n    &lt;form action=\"{{ route('admin.roles.permissions.update', $role) }}\" method=\"POST\"&gt;\n        @csrf\n        @method('PUT')\n        &lt;h4&gt;{{ $role-&gt;name }}&lt;\/h4&gt;\n        @foreach($permissions as $permission)\n            &lt;label&gt;\n                &lt;input type=\"checkbox\" \n                       name=\"permissions[]\" \n                       value=\"{{ $permission-&gt;name }}\"\n                       {{ $role-&gt;hasPermissionTo($permission) ? 'checked' : '' }}&gt;\n                {{ $permission-&gt;name }}\n            &lt;\/label&gt;\n        @endforeach\n        &lt;button type=\"submit\"&gt;\u66f4\u65b0&lt;\/button&gt;\n    &lt;\/form&gt;\n@endforeach<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">\u8907\u6570\u30c1\u30fc\u30e0\u5bfe\u5fdc\u306e\u6a29\u9650\u8a2d\u8a08<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30c1\u30fc\u30e0\u5bfe\u5fdc\u306e\u30e2\u30c7\u30eb\u8a2d\u8a08<\/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\/Team.php\nclass Team extends Model\n{\n    public function users()\n    {\n        return $this-&gt;hasMany(User::class);\n    }\n}\n\n\/\/ app\/Models\/User.php\nclass User extends Authenticatable\n{\n    use HasRoles;\n\n    public function team()\n    {\n        return $this-&gt;belongsTo(Team::class);\n    }\n\n    \/\/ \u30c1\u30fc\u30e0\u5185\u3067\u306e\u6a29\u9650\u30c1\u30a7\u30c3\u30af\n    public function hasTeamPermission($permission)\n    {\n        return $this-&gt;hasPermissionTo($permission) &amp;&amp; \n               $this-&gt;team_id === request()-&gt;team-&gt;id;\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30c1\u30fc\u30e0\u5225\u6a29\u9650\u306e\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u5b9f\u88c5<\/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=\"\">class CheckTeamPermission\n{\n    public function handle($request, Closure $next, $permission)\n    {\n        if (!$request-&gt;user()-&gt;hasTeamPermission($permission)) {\n            abort(403);\n        }\n        return $next($request);\n    }\n}\n\n\/\/ routes\/web.php \u3067\u306e\u4f7f\u7528\u4f8b\nRoute::middleware(['auth', 'team.permission:edit articles'])\n    -&gt;group(function () {\n        Route::resource('articles', ArticleController::class);\n    });<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-14\">\u52d5\u7684\u306a\u6a29\u9650\u4ed8\u4e0e\u30b7\u30b9\u30c6\u30e0<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u52d5\u7684\u6a29\u9650\u30b5\u30fc\u30d3\u30b9\u306e\u5b9f\u88c5<\/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=\"\">class DynamicPermissionService\n{\n    public function grantTemporaryPermission(User $user, $permission, $duration)\n    {\n        \/\/ \u4e00\u6642\u7684\u306a\u6a29\u9650\u3092\u4ed8\u4e0e\n        $user-&gt;givePermissionTo($permission);\n\n        \/\/ \u6a29\u9650\u306e\u6709\u52b9\u671f\u9650\u3092\u8a2d\u5b9a\n        Cache::put(\n            \"temp_permission:{$user-&gt;id}:{$permission}\",\n            now()-&gt;addMinutes($duration),\n            $duration\n        );\n    }\n\n    public function checkTemporaryPermission(User $user, $permission)\n    {\n        $expiryTime = Cache::get(\"temp_permission:{$user-&gt;id}:{$permission}\");\n\n        if ($expiryTime &amp;&amp; now()-&gt;lt($expiryTime)) {\n            return true;\n        }\n\n        \/\/ \u671f\u9650\u5207\u308c\u306e\u6a29\u9650\u3092\u524a\u9664\n        $user-&gt;revokePermissionTo($permission);\n        return false;\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u52d5\u7684\u6a29\u9650\u306e\u30df\u30c9\u30eb\u30a6\u30a7\u30a2<\/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=\"\">class CheckDynamicPermission\n{\n    public function handle($request, Closure $next, $permission)\n    {\n        $user = $request-&gt;user();\n        $permissionService = app(DynamicPermissionService::class);\n\n        if (!$permissionService-&gt;checkTemporaryPermission($user, $permission)) {\n            abort(403);\n        }\n\n        return $next($request);\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-15\">API\u3067\u306e\u6a29\u9650\u7ba1\u7406\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>API\u7528\u306e\u6a29\u9650\u30c1\u30a7\u30c3\u30af<\/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=\"\">class PermissionApiController extends Controller\n{\n    public function check(Request $request)\n    {\n        return response()-&gt;json([\n            'permissions' =&gt; $request-&gt;user()-&gt;getAllPermissions()\n                -&gt;pluck('name'),\n            'roles' =&gt; $request-&gt;user()-&gt;getRoleNames()\n        ]);\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>Sanctum\u3092\u4f7f\u7528\u3057\u305fAPI\u8a8d\u8a3c\u3068\u6a29\u9650\u30c1\u30a7\u30c3\u30af<\/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=\"\">Route::middleware(['auth:sanctum', 'permission:api.access'])\n    -&gt;prefix('api')\n    -&gt;group(function () {\n        Route::get('\/protected-data', function (Request $request) {\n            return response()-&gt;json([\n                'data' =&gt; 'This is protected data',\n                'user_permissions' =&gt; $request-&gt;user()\n                    -&gt;permissions-&gt;pluck('name')\n            ]);\n        });\n    });<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-16\">\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u6d3b\u7528\u3057\u305f\u9ad8\u901f\u306a\u6a29\u9650\u30c1\u30a7\u30c3\u30af<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u30b5\u30fc\u30d3\u30b9\u306e\u5b9f\u88c5<\/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=\"\">class PermissionCacheService\n{\n    private $cache;\n    private $ttl;\n\n    public function __construct()\n    {\n        $this-&gt;cache = Cache::store('redis');\n        $this-&gt;ttl = 60; \/\/ minutes\n    }\n\n    public function getUserPermissions(User $user)\n    {\n        $cacheKey = \"user_permissions:{$user-&gt;id}\";\n\n        return $this-&gt;cache-&gt;remember($cacheKey, $this-&gt;ttl, function () use ($user) {\n            return $user-&gt;getAllPermissions()-&gt;pluck('name')-&gt;toArray();\n        });\n    }\n\n    public function clearUserPermissions(User $user)\n    {\n        $this-&gt;cache-&gt;forget(\"user_permissions:{$user-&gt;id}\");\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u5229\u7528\u3057\u305f\u9ad8\u901f\u306a\u6a29\u9650\u30c1\u30a7\u30c3\u30af<\/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=\"\">class OptimizedPermissionMiddleware\n{\n    private $permissionCache;\n\n    public function __construct(PermissionCacheService $permissionCache)\n    {\n        $this-&gt;permissionCache = $permissionCache;\n    }\n\n    public function handle($request, Closure $next, $permission)\n    {\n        $user = $request-&gt;user();\n        $permissions = $this-&gt;permissionCache-&gt;getUserPermissions($user);\n\n        if (!in_array($permission, $permissions)) {\n            abort(403);\n        }\n\n        return $next($request);\n    }\n}<\/pre>\n\n\n\n<p>\u5404\u30d1\u30bf\u30fc\u30f3\u306f\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u8981\u4ef6\u306b\u5fdc\u3058\u3066\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3057\u3066\u4f7f\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u7279\u306b\u5927\u898f\u6a21\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u30d1\u30bf\u30fc\u30f3\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u5805\u7262\u306a\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u3092\u69cb\u7bc9\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-17\">\u91cd\u8981\u306a\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b03\u9078<\/h2>\n\n\n\n<p>Laravel Permission\u3092\u5b9f\u88c5\u3059\u308b\u969b\u306b\u3088\u304f\u906d\u9047\u3059\u308b\u554f\u984c\u3068\u305d\u306e\u89e3\u6c7a\u65b9\u6cd5\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-18\">\u6a29\u9650\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u66f4\u65b0\u554f\u984c\u3068\u89e3\u6c7a\u7b56<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u6574\u5408\u6027\u554f\u984c<\/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\u3042\u308b\u5b9f\u88c5\u4f8b\n$role-&gt;givePermissionTo('edit articles');\n\/\/ \u3053\u306e\u6642\u70b9\u3067\u30ad\u30e3\u30c3\u30b7\u30e5\u304c\u66f4\u65b0\u3055\u308c\u3066\u3044\u306a\u3044\n\n\/\/ \u89e3\u6c7a\u7b56\uff1a\u30ad\u30e3\u30c3\u30b7\u30e5\u30af\u30ea\u30a2\u3092\u884c\u3046\u30b5\u30fc\u30d3\u30b9\u30af\u30e9\u30b9\u306e\u5b9f\u88c5\nclass PermissionCacheManager\n{\n    public function clearUserPermissionCache(User $user)\n    {\n        \/\/ \u7279\u5b9a\u30e6\u30fc\u30b6\u30fc\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u30af\u30ea\u30a2\n        app()-&gt;make(\\Spatie\\Permission\\PermissionRegistrar::class)\n            -&gt;forgetCachedPermissions();\n\n        \/\/ Redis\u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u5834\u5408\u306e\u8ffd\u52a0\u30af\u30ea\u30a2\u51e6\u7406\n        Cache::tags(['permission_cache', \"user_{$user-&gt;id}\"])-&gt;flush();\n    }\n\n    public function refreshPermissionCache()\n    {\n        \/\/ \u5168\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u518d\u69cb\u7bc9\n        $registrar = app()-&gt;make(\\Spatie\\Permission\\PermissionRegistrar::class);\n        $registrar-&gt;forgetCachedPermissions();\n        $registrar-&gt;registerPermissions();\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30a4\u30d9\u30f3\u30c8\u30ea\u30b9\u30ca\u30fc\u306b\u3088\u308b\u81ea\u52d5\u30ad\u30e3\u30c3\u30b7\u30e5\u66f4\u65b0<\/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=\"\">class PermissionEventSubscriber\n{\n    private $cacheManager;\n\n    public function __construct(PermissionCacheManager $cacheManager)\n    {\n        $this-&gt;cacheManager = $cacheManager;\n    }\n\n    public function handleRoleAssigned($event)\n    {\n        $this-&gt;cacheManager-&gt;clearUserPermissionCache($event-&gt;user);\n    }\n\n    public function handlePermissionAssigned($event)\n    {\n        $this-&gt;cacheManager-&gt;clearUserPermissionCache($event-&gt;user);\n    }\n\n    public function subscribe($events)\n    {\n        $events-&gt;listen(\n            'Spatie\\Permission\\Events\\RoleAssigned',<\/pre>\n\n\n[self::class, \u2018handleRoleAssigned\u2019]\n\n\n\n<p>); $events-&gt;listen( \u2018Spatie\\Permission\\Events\\PermissionAssigned\u2019,<\/p>\n\n\n[self::class, \u2018handlePermissionAssigned\u2019]\n\n\n\n<p>); } }<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-19\">N+1\u554f\u984c\u306e\u56de\u907f\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Eager\u30ed\u30fc\u30c7\u30a3\u30f3\u30b0\u306e\u9069\u5207\u306a\u4f7f\u7528<\/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\u3042\u308b\u30af\u30a8\u30ea\n$users = User::all();\nforeach ($users as $user) {\n    $permissions = $user-&gt;permissions; \/\/ N+1\u554f\u984c\u767a\u751f\n}\n\n\/\/ \u89e3\u6c7a\u7b56\uff1a\u9069\u5207\u306aEager\u30ed\u30fc\u30c7\u30a3\u30f3\u30b0\n$users = User::with(['roles.permissions', 'permissions'])-&gt;get();\n\n\/\/ \u30ab\u30b9\u30bf\u30e0\u30b9\u30b3\u30fc\u30d7\u306e\u4f5c\u6210\nclass User extends Authenticatable\n{\n    use HasRoles;\n\n    public function scopeWithFullPermissions($query)\n    {\n        return $query-&gt;with([\n            'roles.permissions',\n            'permissions',\n            'roles' =&gt; function ($query) {\n                $query-&gt;select('id', 'name');\n            },\n            'permissions' =&gt; function ($query) {\n                $query-&gt;select('id', 'name');\n            }\n        ]);\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$users = User::withFullPermissions()-&gt;get();<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30af\u30a8\u30ea\u306e\u6700\u9069\u5316<\/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=\"\">class PermissionOptimizer\n{\n    public function getUsersWithPermission($permission)\n    {\n        return User::select('users.*')\n            -&gt;join('model_has_permissions', function ($join) {\n                $join-&gt;on('model_has_permissions.model_id', '=', 'users.id')\n                    -&gt;where('model_has_permissions.model_type', User::class);\n            })\n            -&gt;join('permissions', 'permissions.id', '=', 'model_has_permissions.permission_id')\n            -&gt;where('permissions.name', $permission)\n            -&gt;distinct()\n            -&gt;get();\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-20\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30af\u30a8\u30ea\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u5b9f\u88c5<\/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=\"\">class OptimizedPermissionService\n{\n    private $cache;\n    private $ttl;\n\n    public function __construct()\n    {\n        $this-&gt;cache = Cache::store('redis');\n        $this-&gt;ttl = config('permission.cache.expiration_time');\n    }\n\n    public function getUsersWithPermission($permission)\n    {\n        $cacheKey = \"users_with_permission:{$permission}\";\n\n        return $this-&gt;cache-&gt;remember($cacheKey, $this-&gt;ttl, function () use ($permission) {\n            return User::permission($permission)\n                -&gt;select(['id', 'name', 'email'])\n                -&gt;get();\n        });\n    }\n\n    public function invalidatePermissionCache($permission = null)\n    {\n        if ($permission) {\n            $this-&gt;cache-&gt;forget(\"users_with_permission:{$permission}\");\n        } else {\n            \/\/ \u5168\u6a29\u9650\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u30af\u30ea\u30a2\n            $permissions = Permission::pluck('name');\n            foreach ($permissions as $perm) {\n                $this-&gt;cache-&gt;forget(\"users_with_permission:{$perm}\");\n            }\n        }\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u6700\u9069\u5316<\/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=\"\">\/\/ \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u5411\u4e0a\u306e\u305f\u3081\u306e\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\nclass OptimizePermissionIndexes extends Migration\n{\n    public function up()\n    {\n        Schema::table('model_has_permissions', function (Blueprint $table) {\n            \/\/ \u8907\u5408\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u8ffd\u52a0\n            $table-&gt;index(\n                ['model_id', 'model_type', 'permission_id'],\n                'model_has_permissions_compound_index'\n            );\n        });\n\n        Schema::table('role_has_permissions', function (Blueprint $table) {\n            $table-&gt;index(\n                ['role_id', 'permission_id'],\n                'role_has_permissions_compound_index'\n            );\n        });\n    }\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u6a29\u9650\u30c1\u30a7\u30c3\u30af\u306e\u6700\u9069\u5316<\/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=\"\">class OptimizedPermissionChecker\n{\n    private $permissionCache = [];\n\n    public function checkPermission(User $user, $permission)\n    {\n        $cacheKey = \"{$user-&gt;id}:{$permission}\";\n\n        if (!isset($this-&gt;permissionCache[$cacheKey])) {\n            $this-&gt;permissionCache[$cacheKey] = $user-&gt;hasPermissionTo($permission);\n        }\n\n        return $this-&gt;permissionCache[$cacheKey];\n    }\n\n    public function clearCache(User $user = null)\n    {\n        if ($user) {\n            foreach ($this-&gt;permissionCache as $key =&gt; $value) {\n                if (strpos($key, \"{$user-&gt;id}:\") === 0) {\n                    unset($this-&gt;permissionCache[$key]);\n                }\n            }\n        } else {\n            $this-&gt;permissionCache = [];\n        }\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u6700\u9069\u5316\u3068\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u624b\u6cd5\u3092\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001Laravel Permission\u3092\u4f7f\u7528\u3057\u305f\u30b7\u30b9\u30c6\u30e0\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3068\u4fe1\u983c\u6027\u3092\u5927\u5e45\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-21\">Laravel\u6a29\u9650\u306e\u5fdc\u7528\u3068\u767a\u5c55<\/h2>\n\n\n\n<p>\u3088\u308a\u9ad8\u5ea6\u306a\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u306e\u5b9f\u88c5\u65b9\u6cd5\u306b\u3064\u3044\u3066\u3001\u5b9f\u8df5\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u3068\u3068\u3082\u306b\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-22\">\u30c6\u30b9\u30c8\u74b0\u5883\u3067\u306e\u6a29\u9650\u7ba1\u7406\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u6a29\u9650\u30c6\u30b9\u30c8\u306e\u57fa\u672c\u8a2d\u5b9a<\/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=\"\">namespace Tests;\n\nuse Spatie\\Permission\\Models\\Role;\nuse Spatie\\Permission\\Models\\Permission;\n\nclass PermissionTestCase extends TestCase\n{\n    protected function setupPermissions()\n    {\n        \/\/ \u30c6\u30b9\u30c8\u7528\u306e\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u3092\u4f5c\u6210\n        $permissions = [\n            'view articles',\n            'create articles',\n            'edit articles',\n            'delete articles'\n        ];\n\n        foreach ($permissions as $permission) {\n            Permission::create(['name' =&gt; $permission]);\n        }\n\n        \/\/ \u30c6\u30b9\u30c8\u7528\u306e\u30ed\u30fc\u30eb\u3092\u4f5c\u6210\n        $editorRole = Role::create(['name' =&gt; 'editor']);\n        $editorRole-&gt;givePermissionTo([\n            'view articles',\n            'create articles',\n            'edit articles'\n        ]);\n    }\n\n    protected function createUserWithPermissions($permissions)\n    {\n        $user = User::factory()-&gt;create();\n        $user-&gt;givePermissionTo($permissions);\n        return $user;\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u6a5f\u80fd\u30c6\u30b9\u30c8\u306e\u5b9f\u88c5\u4f8b<\/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=\"\">class ArticlePermissionTest extends PermissionTestCase\n{\n    public function setUp(): void\n    {\n        parent::setUp();\n        $this-&gt;setupPermissions();\n    }\n\n    \/** @test *\/\n    public function user_with_edit_permission_can_update_article()\n    {\n        $user = $this-&gt;createUserWithPermissions(['edit articles']);\n        $article = Article::factory()-&gt;create();\n\n        $response = $this-&gt;actingAs($user)\n            -&gt;putJson(\"\/api\/articles\/{$article-&gt;id}\", [\n                'title' =&gt; 'Updated Title'\n            ]);\n\n        $response-&gt;assertStatus(200);\n        $this-&gt;assertEquals('Updated Title', $article-&gt;fresh()-&gt;title);\n    }\n\n    \/** @test *\/\n    public function user_without_permission_cannot_update_article()\n    {\n        $user = $this-&gt;createUserWithPermissions(['view articles']);\n        $article = Article::factory()-&gt;create();\n\n        $response = $this-&gt;actingAs($user)\n            -&gt;putJson(\"\/api\/articles\/{$article-&gt;id}\", [\n                'title' =&gt; 'Updated Title'\n            ]);\n\n        $response-&gt;assertStatus(403);\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-23\">\u30ab\u30b9\u30bf\u30e0\u30ac\u30fc\u30c9\u3068\u306e\u9023\u643a\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30ab\u30b9\u30bf\u30e0\u8a8d\u8a3c\u30ac\u30fc\u30c9\u306e\u5b9f\u88c5<\/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=\"\">class CustomAuthGuard extends TokenGuard\n{\n    public function user()\n    {\n        if ($this-&gt;user !== null) {\n            return $this-&gt;user;\n        }\n\n        $user = null;\n        $token = $this-&gt;getTokenForRequest();\n\n        if ($token) {\n            $user = $this-&gt;provider-&gt;retrieveByCredentials([\n                'api_token' =&gt; hash('sha256', $token),\n                'is_active' =&gt; true\n            ]);\n        }\n\n        return $this-&gt;user = $user;\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30ab\u30b9\u30bf\u30e0\u30ac\u30fc\u30c9\u3068\u6a29\u9650\u306e\u9023\u643a<\/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=\"\">class CustomPermissionMiddleware\n{\n    public function handle($request, Closure $next, $permission)\n    {\n        $guard = config('auth.defaults.guard');\n        $user = auth($guard)-&gt;user();\n\n        if (!$user || !$user-&gt;checkPermissionFor($guard, $permission)) {\n            throw new UnauthorizedException(403);\n        }\n\n        return $next($request);\n    }\n}\n\n\/\/ User \u30e2\u30c7\u30eb\u306e\u62e1\u5f35\nclass User extends Authenticatable\n{\n    use HasRoles;\n\n    public function checkPermissionFor($guard, $permission)\n    {\n        return $this-&gt;hasPermissionTo($permission, $guard);\n    }\n}\n\n\/\/ \u8a2d\u5b9a\u306e\u8ffd\u52a0\uff08config\/auth.php\uff09\n'guards' =&gt; [\n    'custom' =&gt; [\n        'driver' =&gt; 'custom',\n        'provider' =&gt; 'users',\n    ],\n],<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-24\">\u30de\u30eb\u30c1\u30c6\u30ca\u30f3\u30c8\u3067\u306e\u6a29\u9650\u8a2d\u8a08\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30c6\u30ca\u30f3\u30c8\u5225\u6a29\u9650\u30b7\u30b9\u30c6\u30e0\u306e\u5b9f\u88c5<\/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=\"\">class Tenant extends Model\n{\n    public function roles()\n    {\n        return $this-&gt;hasMany(Role::class);\n    }\n\n    public function permissions()\n    {\n        return $this-&gt;hasMany(Permission::class);\n    }\n}\n\nclass TenantScope implements Scope\n{\n    public function apply(Builder $builder, Model $model)\n    {\n        $builder-&gt;where('tenant_id', session('tenant_id'));\n    }\n}\n\nclass TenantRole extends Model\n{\n    use HasPermissions;\n\n    protected static function boot()\n    {\n        parent::boot();\n        static::addGlobalScope(new TenantScope);\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30c6\u30ca\u30f3\u30c8\u9593\u306e\u6a29\u9650\u5206\u96e2<\/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=\"\">class TenantPermissionService\n{\n    public function assignRoleToUser(User $user, $roleName, Tenant $tenant)\n    {\n        $role = $tenant-&gt;roles()\n            -&gt;where('name', $roleName)\n            -&gt;firstOrFail();\n\n        $user-&gt;assignRole($role);\n    }\n\n    public function syncTenantPermissions(Tenant $tenant, array $permissions)\n    {\n        return DB::transaction(function () use ($tenant, $permissions) {\n            \/\/ \u65e2\u5b58\u306e\u6a29\u9650\u3092\u30af\u30ea\u30a2\n            $tenant-&gt;permissions()-&gt;delete();\n\n            \/\/ \u65b0\u3057\u3044\u6a29\u9650\u3092\u4f5c\u6210\n            $permissionModels = collect($permissions)-&gt;map(function ($permission) use ($tenant) {\n                return new Permission([\n                    'name' =&gt; $permission,\n                    'tenant_id' =&gt; $tenant-&gt;id,\n                    'guard_name' =&gt; 'web'\n                ]);\n            });\n\n            return $tenant-&gt;permissions()-&gt;saveMany($permissionModels);\n        });\n    }\n\n    public function checkTenantPermission(User $user, $permission, Tenant $tenant)\n    {\n        return $user-&gt;hasPermissionTo($permission) &amp;&amp; \n               $user-&gt;tenant_id === $tenant-&gt;id;\n    }\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30c6\u30ca\u30f3\u30c8\u5207\u308a\u66ff\u3048\u6642\u306e\u6a29\u9650\u7ba1\u7406<\/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=\"\">class TenantSwitcher\n{\n    public function switchTenant(User $user, Tenant $tenant)\n    {\n        \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u306b\u30c6\u30ca\u30f3\u30c8\u60c5\u5831\u3092\u4fdd\u5b58\n        session(['tenant_id' =&gt; $tenant-&gt;id]);\n\n        \/\/ \u6a29\u9650\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u30af\u30ea\u30a2\n        app()-&gt;make(\\Spatie\\Permission\\PermissionRegistrar::class)\n            -&gt;forgetCachedPermissions();\n\n        \/\/ \u30c6\u30ca\u30f3\u30c8\u56fa\u6709\u306e\u6a29\u9650\u3092\u518d\u8aad\u307f\u8fbc\u307f\n        $user-&gt;load(['roles' =&gt; function ($query) use ($tenant) {\n            $query-&gt;where('tenant_id', $tenant-&gt;id);\n        }]);\n\n        return $user-&gt;fresh();\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u9ad8\u5ea6\u306a\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u67d4\u8edf\u3067\u5805\u7262\u306a\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u3092\u69cb\u7bc9\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u7279\u306b\u30de\u30eb\u30c1\u30c6\u30ca\u30f3\u30c8\u74b0\u5883\u3067\u306f\u3001\u30c6\u30ca\u30f3\u30c8\u9593\u306e\u30c7\u30fc\u30bf\u5206\u96e2\u3068\u6a29\u9650\u306e\u9069\u5207\u306a\u7ba1\u7406\u304c\u91cd\u8981\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\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-2700","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\/2700","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=2700"}],"version-history":[{"count":2,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2700\/revisions"}],"predecessor-version":[{"id":2702,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2700\/revisions\/2702"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2700"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2700"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2700"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}