<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] ### **1、簡介** 除了提供開箱即用的[認證服務](http://laravelacademy.org/post/3074.html)之外,[Laravel](http://laravelacademy.org/tags/laravel "View all posts in Laravel")?還提供了一個簡單的方式來管理[授權](http://laravelacademy.org/tags/%e6%8e%88%e6%9d%83 "View all posts in 授權")邏輯以便控制對資源的訪問權限。在 Laravel 中,有多種方法和[輔助函數](http://laravelacademy.org/tags/%e8%be%85%e5%8a%a9%e5%87%bd%e6%95%b0 "View all posts in 輔助函數")來協助你管理授權邏輯,本[文檔](http://laravelacademy.org/tags/%e6%96%87%e6%a1%a3 "View all posts in 文檔")將會一一覆蓋這些方法。 ### **2、定義權限(Abilities)** 判斷[用戶](http://laravelacademy.org/tags/%e7%94%a8%e6%88%b7 "View all posts in 用戶")是否有權限執行給定動作的最簡單方式就是使用?`Illuminate\Auth\Access\[Gate](http://laravelacademy.org/tags/gate "View all posts in Gate")`?類來定義一個“權限”。我們在`AuthServiceProvider`?中定義所有權限,例如,我們來定義一個接收當前?`User`?和?`Post`?[模型](http://laravelacademy.org/post/2995.html)的`update-post`權限,在該權限中,我們判斷用戶?`id`?是否和文章的?`user_id`?匹配: ~~~ <?php namespace App\Providers; use Illuminate\Contracts\Auth\Access\Gate as GateContract; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider{ /** * 注冊應用所有的認證/授權服務. * * @param \Illuminate\Contracts\Auth\Access\Gate $gate * @return void */ public function boot(GateContract $gate) { parent::registerPolicies($gate); $gate->define('update-post', function ($user, $post) { return $user->id === $post->user_id; }); } } ~~~ 注意我們并沒有檢查給定?`$user`?是否為?`NULL`,當用戶未經過登錄認證或者用戶沒有通過?`forUser`?方法指定,`Gate`?會自動為所有權限返回?`false`。 ##### **基于類的權限** 除了注冊授權回調閉包之外,還可以通過傳遞包含權限類名和類方法的方式來注冊權限方法,當需要的時候,該類會通過[服務容器](http://laravelacademy.org/post/2910.html)進行解析: ~~~ $gate->define('update-post', 'PostPolicy@update'); ~~~ ##### **攔截認證檢查** 有時候,你可能希望對指定用戶授予所有權限,在這種場景中,需要使用?`before`?方法定義一個在所有其他授權檢查之前運行的回調: ~~~ $gate->before(function?($user,?$ability)?{ if?($user->isSuperAdmin())?{ return?true; } }); ~~~ 如果?`before`?回調返回一個非空結果,那么該結果則會被當做檢查的結果。 你也可以使用?`after`?方法定義一個在所有其他授權檢查之后運行的回調,所不同的是,在?`after`?回調中你不能編輯授權檢查的結果: ~~~ $gate->after(function?($user,?$ability,?$result,?$arguments)?{ // }); ~~~ ### **3、檢查權限(Abilities)** #### **通過 Gate 門面** 權限定義好之后,可以使用多種方式來“檢查”。首先,可以使用?`Gate`?[門面](http://laravelacademy.org/post/2920.html)的?`check`,?`allows`, 或者`denies`?方法。所有這些方法都接收權限名和傳遞給該權限回調的參數作為參數。你不需要傳遞當前用戶到這些方法,因為?`Gate`?會自動附加當前用戶到傳遞給回調的參數,因此,當檢查我們之前定義的?`update-post`?權限時,我們只需要傳遞一個`Post`?實例到?`denies`?方法: ~~~ <?php namespace App\Http\Controllers; use Gate; use App\User; use App\Post; use App\Http\Controllers\Controller; class PostController extends Controller{ /** * 更新給定文章 * * @param int $id * @return Response */ public function update($id) { $post = Post::findOrFail($id); if (Gate::denies('update-post', $post)) { abort(403); } // 更新文章... } } ~~~ 當然,`allows`?方法和?`denies`?方法是相對的,如果動作被授權會返回?`true`?,`check`?方法是?`allows`?方法的別名。 ##### **為指定用戶檢查權限** 如果你想要使用?`Gate`?門面判斷非當前用戶是否有權限,可以使用?`forUser`?方法: ~~~ if (Gate::forUser($user)->allows('update-post', $post)) { // } ~~~ ##### **傳遞多個參數** 當然,權限回調還可以接收多個參數: ~~~ Gate::define('delete-comment', function ($user, $post, $comment) { // }); ~~~ 如果權限需要多個參數,簡單傳遞參數數組到?`Gate`?方法: ~~~ if (Gate::allows('delete-comment', [$post, $comment])) { // } ~~~ #### **通過 User?[模型](http://laravelacademy.org/tags/%e6%a8%a1%e5%9e%8b "View all posts in 模型")** 還可以通過?`User`?模型實例來檢查權限。默認情況下,Laravel 的?`App\User`?模型使用一個?`Authorizable`?trait來提供兩種方法:`can`?和?`cannot`。這兩個方法的功能和?`Gate`?門面上的?`allows`?和?`denies`?方法類似。因此,使用我們前面的例子,可以修改代碼如下: ~~~ <?php namespace App\Http\Controllers; use App\Post; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class PostController extends Controller{ /** * 更新給定文章 * * @param \Illuminate\Http\Request $request * @param int $id * @return Response */ public function update(Request $request, $id) { $post = Post::findOrFail($id); if ($request->user()->cannot('update-post', $post)) { abort(403); } // 更新文章... } } ~~~ 當然,`can`?方法和?`cannot`?方法相反: ~~~ if ($request->user()->can('update-post', $post)) { // 更新文章... } ~~~ #### **在?****[Blade](http://laravelacademy.org/tags/blade "View all posts in Blade")?****模板引擎中檢查** 為了方便,Laravel 提供了 Blade 指令?`@can`?來快速檢查當前用戶是否有指定權限。例如: ~~~ <a href="/post/{{ $post->id }}">View Post</a> @can('update-post', $post) <a href="/post/{{ $post->id }}/edit">Edit Post</a> @endcan ~~~ 你還可以將?`@can`?指令和?`@else`?指令聯合起來使用: ~~~ @can('update-post', $post) <!-- The Current User Can Update The Post --> @else <!-- The Current User Can't Update The Post --> @endcan ~~~ #### **在[表單](http://laravelacademy.org/tags/%e8%a1%a8%e5%8d%95 "View all posts in 表單")請求中檢查** 你還可以選擇在表單請求的?`authorize`?方法中使用?`Gate`?定義的權限。例如: ~~~ /** * 判斷請求用戶是否經過授權 * * @return bool */ public function authorize(){ $postId = $this->route('post'); return Gate::allows('update', Post::findOrFail($postId)); } ~~~ ### **4、[策略](http://laravelacademy.org/tags/%e7%ad%96%e7%95%a5 "View all posts in 策略")類(Policies)** #### **創建策略類** 由于在?`AuthServiceProvider`?中定義所有的授權邏輯將會變得越來越臃腫笨重,尤其是在大型應用中,所以 Laravel 允許你將授權邏輯分割到多個“策略”類中,策略類是原生的PHP類,基于授權資源對授權邏輯進行分組。 首先,讓我們生成一個策略類來管理對?`Post`?模型的授權,你可以使用 Artisan 命令?`make:policy`?來生成該策略類。生成的策略類位于?`app/Policies`?目錄: ~~~ php artisan make:policy PostPolicy ~~~ ##### **注冊策略類** 策略類生成后我們需要將其注冊到?`Gate`?類。`AuthServiceProvider`?包含了一個?`policies`?屬性來映射實體及管理該實體的策略類。因此,我們指定?`Post`?模型的策略類是?`PostPolicy`: ~~~ <?php namespace?App\Providers; use?App\Post; use?App\Policies\PostPolicy; use?Illuminate\Contracts\Auth\Access\Gate?as?GateContract; use?Illuminate\Foundation\Support\Providers\AuthServiceProvider?as?ServiceProvider; class?AuthServiceProvider?extends?ServiceProvider{ /** *?應用的策略映射 * *?@var?array */ protected?$policies?=?[ Post::class?=>?PostPolicy::class, ]; ? ??/** ? ? ?* 注冊所有應用認證/授權服務 ? ? ?* ? ? ?* @param \Illuminate\Contracts\Auth\Access\Gate $gate ? ?? * @return void ? ? ?*/ ? ? public function boot(GateContract $gate) ? ? { ? ? ? ? $this->registerPolicies($gate); ? ? } } ~~~ #### **編寫策略類** 策略類生成和注冊后,我們可以為授權的每個權限添加方法。例如,我們在?`PostPolicy`?中定義一個?`update`?方法,該方法判斷給定?`User`?是否可以更新某個?`Post`: ~~~ <?php namespace App\Policies; use App\User; use App\Post; class PostPolicy{ /** * 判斷給定文章是否可以被給定用戶更新 * * @param \App\User $user * @param \App\Post $post * @return bool */ public function update(User $user, Post $post) { return $user->id === $post->user_id; } } ~~~ 你可以繼續在策略類中為授權的權限定義更多需要的方法,例如,你可以定義?`show`,?`destroy`, 或者?`addComment`?方法來認證多個?`Post`?動作。 > 注意:所有策略類都通過服務容器進行解析,這意味著你可以在策略類的構造函數中類型提示任何依賴,它們將會自動被注入。 ##### **攔截所有檢查** 有時候,你可能希望對指定用戶授予所有權限,在這種場景中,需要使用?`before`?方法定義一個在所有其他授權檢查之前運行的回調: ~~~ $gate->before(function?($user,?$ability)?{ if?($user->isSuperAdmin())?{ return?true; } }); ~~~ 如果?`before`?回調返回一個非空結果,那么該結果則會被當做檢查的結果。 #### **檢查策略** 策略類方法的調用方式和基于授權回調的閉包一樣,你可以使用?`Gate`?門面,`User`?模型,`@can`?指令或者輔助函數`policy`。 ##### **通過 Gate 門面** `Gate`?將會自動通過檢測傳遞過來的類參數來判斷使用哪一個策略類,因此,如果傳遞一個?`Post`?實例給`denies`?方法,相應的,`Gate`?會使用?`PostPolicy`?來進行動作授權: ~~~ <?php namespace App\Http\Controllers; use Gate; use App\User; use App\Post; use App\Http\Controllers\Controller; class PostController extends Controller{ /** * 更新給定文章 * * @param int $id * @return Response */ public function update($id) { $post = Post::findOrFail($id); if (Gate::denies('update', $post)) { abort(403); } // 更新文章... } } ~~~ ##### **通過 User 模型** `User`?模型的?`can`?和?`cannot`?方法也會自動判斷給定參數對應的策略類。這些方法提供了便利的方式來為應用接收到的任意?`User`?實例進行授權: ~~~ if?($user->can('update',?$post))?{ // } if?($user->cannot('update',?$post))?{ // } ~~~ ##### **在 Blade 模板中使用** 類似的,Blade 指令?`@can`?將會使用參數中有效的策略類: ~~~ @can('update', $post) <!-- The Current User Can Update The Post --> @endcan ~~~ ##### **通過輔助函數 policy** 全局的輔助函數?`policy`?用于為給定類實例接收策略類。例如,我們可以傳遞一個?`Post`?實例給幫助函數`policy`?來獲取相應的?`PostPolicy`?類的實例: ~~~ if (policy($post)->update($user, $post)) { // } ~~~ ### **5、[控制器](http://laravelacademy.org/tags/%e6%8e%a7%e5%88%b6%e5%99%a8 "View all posts in 控制器")授權** 默認情況下,Laravel 自帶的控制器基類?`App\Http\Controllers\Controller`?使用了?`AuthorizesRequests`?trait,該 trait 提供了可用于快速授權給定動作的?`authorize`?方法,如果授權不通過,則拋出?`HttpException`?異常。 該?`authorize`?方法和其他多種授權方法使用方法一致,例如?`Gate::allows`?和?`$user->can()`。因此,我們可以這樣使用?`authorize`?方法快速授權更新?`Post`?的請求: ~~~ <?php namespace App\Http\Controllers; use App\Post; use App\Http\Controllers\Controller; class PostController extends Controller{ /** * 更新給定文章 * * @param int $id * @return Response */ public function update($id) { $post = Post::findOrFail($id); $this->authorize('update', $post); // 更新文章... } } ~~~ 如果授權成功,控制器繼續正常執行;然而,如果?`authorize`?方法判斷該動作授權失敗,將會拋出`HttpException`?異常并生成帶?`403 Not Authorized`?狀態碼的HTTP響應。正如你所看到的,`authorize`?方法是一個授權動作、拋出異常的便捷方法。 `AuthorizesRequests`?trait還提供了?`authorizeForUser`?方法用于授權非當前用戶: ~~~ $this->authorizeForUser($user, 'update', $post); ~~~ ##### **自動判斷策略類方法** 通常,一個策略類方法對應一個控制器上的方法,例如,在上面的?`update`?方法中,控制器方法和策略類方法共享同一個方法名:`update`。 正是因為這個原因,Laravel 允許你簡單傳遞實例參數到?`authorize`?方法,被授權的權限將會自動基于調用的方法名進行判斷。在本例中,由于?`authorize`?在控制器的?`update`?方法中被調用,那么對應的,`PostPolicy`?上?`update`方法將會被調用: ~~~ /** *?更新給定文章 * *?@param? int? $id *?@return?Response */ public?function?update($id){ $post?=?Post::findOrFail($id); $this->authorize($post); //?更新文章... } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看