[TOC]
Guard 定義了用戶在每個請求中如何實現認證
# 配置
在config/auth.php中
```
'guards' => [
'admin'=>[
'driver' => 'session', //驅動
'provider' => 'admin', //由什么提供
],
],
'providers' => [
'admin' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
```
在Admin.php這個模型中編輯
```
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
//
}
```
# 使用
在控制器中編輯
```
public function user()
{
//我們獲取到的要和數據庫的字段比對
//use Illuminate\Support\Facades\Auth;
//laravel驗證密碼要字段是password這點還沒想到怎么改
if (Auth::guard('admin')->attempt(['username' => '1', 'password' => '123'])) {
// 登錄進來
return Auth::user(); //返回用戶信息
}
return 0;
}
```
---
首先創建一張文章表 `php artisan make:migration create_posts_table --create=posts`
然后創建模型,控制器.在ModelFactory.php中編輯
```php
//新增
$factory->define(App\Post::class, function (Faker\Generator $faker) {
return [
'user_id'=>factory(\App\User::class)->create()->id,
'title'=>$faker->sentence,
'body'=>$faker->paragraph,
];
});
```
運行 `php artisan tinker` 進入交互界面,執行
```
factory('App\Post')->create();
```
生成文章的測試數據
如果使用的是laravel5.1的話,會在User.php模型中看到他use了Authorizable這個類,他會對用戶權限進行細分
在Providers/AuthServiceProvider.php中boot方法編輯
Laravel5.2
```php
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
//這邊意思是判斷用戶是不是文章的作者,這邊的user是已經登錄進來的用戶
//如果用戶沒有登錄進來,自動判斷為錯誤,show-post為自定義的字符串
$gate->define('show-post', function($user,$post){
return $user->id==$post->user_id;
});
}
```
Laravel5.4
```
public function boot()
{
$this->registerPolicies();
//顯示文章.show-post自己定義
//門面
Gate::define('show-post',function ($user,$post){
//判斷這篇文章是不是這個用戶創建的
return $user->id == $post->user_id;
});
}
```
然后在路由中寫 `Route::resource('posts','PostsController');`
在 `PostsController` 控制器中編輯
```php
public function show($id)
{
$post=Post::findOrFail($id);
//讓用戶登錄進來
\Auth::loginUsingId(1);
//use Gate;
if(Gate::denies('show-post',$post)){
abort(403,'sorry');
}
return $post->title;
}
```
也可以這樣寫
```php
public function show($id)
{
$post=Post::findOrFail($id);
//讓用戶登錄進來
\Auth::loginUsingId(1);
$this->authorize('show-post',$post);
return $post->title;
}
```
一樣可以實現.
我們還可以對Providers/AuthServiceProvider.php中boot方法,優化一下
```php
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
$gate->define('show-post', function($user,$post){
return $user->owns($post);
});
}
```
然后我們在User.php模型中寫
```php
public function owns($post)
{
return $this->id==$post->user_id;
}
```
# 如果做資源列表(/posts)的權限怎么做?
我沒進行思考,就直接想加到 policy 里面。
~~~
//PostPolicy
...
public function viewList(User $user, array $posts)
{
//todo
}
...
//PostController
...
$this->authorize('viewList', $posts);
...
~~~
發現不行啊,細細的查看了 Gate 的實現,給你看一個函數你就懂了:
~~~
//Gate.php
protected function firstArgumentCorrespondsToPolicy(array $arguments)
{
if (! isset($arguments[0])) {
return false;
}
if (is_object($arguments[0])) {
return isset($this->policies[get_class($arguments[0])]);
}
return is_string($arguments[0]) && isset($this->policies[$arguments[0]]);
}
~~~
在 authorize 的時候,Gate 會通過第一個參數(除去 user)來判斷是哪個對象,知道了這個對象,才能找到對應的 policy class,所以一般我們這么用:
~~~
$this->authorize('update', $post);
$this->authorize('create', Post::class);
~~~
如果你想用 viewList,可以這么做:
~~~
//PostPolicy
...
public function viewList(User $user, $class, array $posts)
{
//todo
}
...
//PostController
...
$this->authorize('viewList', Post::class, $posts);
...
~~~
是不是覺得很變扭,$class 這個參數我們根本就沒有用,回過頭想一想,這么做好像哪里不太對。。。。。。。。。。。
是的,Policy 本來就是針對單個對象的,我現在要控制列表的權限,正確的做法應該是這樣的:
~~~
\Gate::define('view-post-list', function ($user, $posts) {
//
});
~~~
使用
~~~
//PostController
...
$this->authorize('view-post-list', $posts);
...
~~~
查看 Gate 的代碼,你會發現,他會優先 check policy 是否存在,不存在就會去檢查是否有定義的 abilities,如果有就會使用,貼一段代碼你就懂了:
~~~
protected function resolveAuthCallback($user, $ability, array $arguments)
{
if ($this->firstArgumentCorrespondsToPolicy($arguments)) {
return $this->resolvePolicyCallback($user, $ability, $arguments);
} elseif (isset($this->abilities[$ability])) {
return $this->abilities[$ability];
} else {
return function () {
return false;
};
}
}
~~~
- 配置
- composer安裝
- composer用法
- composer版本約束表達
- phpstorm
- sftp文件同步
- php類型約束
- laradock
- 配置文件緩存詳解
- git
- 自定義函數
- 核心概念
- IOC
- 服務提供者
- Facade
- 契約
- 生命周期
- 路由
- 請求
- 命名路由
- 路由分組
- 資源路由
- 控制器路由
- 響應宏
- 響應
- Command
- 創建命令
- 定時任務
- console路由
- 執行用戶自定義的定時任務
- artisan命令
- 中間件
- 創建中間件
- 使用中間件
- 前置和后置
- 詳細介紹
- 訪問次數限制
- 為 VerifyCsrfToken 添加過濾條件
- 單點登錄
- 事件
- 創建
- ORM
- 簡介
- DB類
- 配置
- CURD
- queryScope和setAttribute
- 查看sql執行過程
- 關聯關系
- 一對一
- 一對多
- 多對多
- 遠程關聯
- 多態一對多
- 多態多對多
- 關聯數據庫的調用
- withDefault
- 跨模型更新時間戳
- withCount,withSum ,withAvg, withMax,withMin
- SQL常見操作
- 模型事件
- 模型事件詳解
- 模型事件與 Observer
- deleted 事件未被觸發
- model validation
- ORM/代碼片段
- Repository模式
- 多重where語句
- 中間表類型轉換
- Collection集合
- 新增的一些方法
- 常見用法
- 求和例子
- 機場登機例子
- 計算github活躍度
- 轉化評論格式
- 計算營業額
- 創建lookup數組
- 重新組織出表和字段關系并且字段排序
- 重構循環
- 其他例子
- 其他問題一
- 去重
- 第二個數組按第一個數組的鍵值排序
- 搜索ES
- 安裝
- 表單
- Request
- sessiom
- Response
- Input
- 表單驗證
- 簡介
- Validator
- Request類
- 接口中的表單驗證
- Lumen 中自定義表單驗證返回消息
- redis
- 廣播事件
- 發布訂閱
- 隊列
- 守護進程
- redis隊列的坑
- beanstalkd
- rabbitmq
- redis隊列
- 日志模塊
- 錯誤
- 日志詳解
- 數據填充與遷移
- 生成數據
- 數據填充seed
- migrate
- 常見錯誤
- Blade模板
- 流程控制
- 子視圖
- URL
- 代碼片段
- Carbon時間類
- 一些用法
- 郵件
- 分頁
- 加密解密
- 緩存
- 文件上傳
- 優化
- 隨記
- 嵌套評論
- 判斷字符串是否是合法的 json 字符串
- 單元測試
- 計算出兩個日期的diff
- 自定義一個類文件讓composer加載
- 時間加減
- 對象數組互轉方法
- 用戶停留過久自動退出登錄
- optional 輔助方法
- 文件下載
- Api
- Dingo api
- auth.basic
- api_token
- Jwt-Auth
- passport
- Auth
- Authentication 和 Authorization
- Auth Facade
- 授權策略
- Gates
- composer包
- debug包
- idehelp包
- image處理
- 驗證碼
- jq插件
- 第三方登錄
- 第三方支付
- log顯示包
- 微信包
- xss過濾
- Excel包
- MongoDB
- php操作
- 聚合查詢
- 發送帶附件郵件
- 中文轉拼音包
- clockwork網頁調試
- emoji表情
- symfony組件
- swooletw/laravel-swoole
- 常見問題
- 跨域問題
- Laravel隊列優先級的一個坑
- cache:clear清除緩存問題
- .env無法讀取
- 源碼相關基礎知識
- __set和__get
- 依賴注入、控制反轉和依賴倒置原則
- 控制反轉容器(Ioc Container)
- 深入服務容器
- call_user_func
- compact
- 中間件簡易實現
- array_reduce
- 中間件實現代碼
- Pipeline管道操作
- composer自動加載
- redis延時隊列
- 了解laravel redis隊列
- cli
- 源碼解讀
- Facade分析
- Facade源碼分析
- IOC服務容器
- 中間件原理
- 依賴注入淺析
- 微信
- 微信公眾號
- 常用接收消息
- 6大接收接口
- 常用被動回復消息
- 接口調用憑證
- 自定義菜單
- 新增素材
- 客服消息
- 二維碼
- 微信語音
- LBS定位
- 網頁授權
- JSSDK
- easywechat
- 小程序
- 小程序配置app.json