- [策略](#policies)
- [隐藏实体资源](#hiding-entire-resources)
- [关系](#relationships)
- [禁用授权](#disabling-authorization)
- [字段](#fields)
- [过滤索引](#index-filtering)
- [可重复的索引](#relatable-filtering)
- [Scout 过滤](#scout-filtering)
当访问 Nova 的用户只有你和你或者公司内部的开发团队时,Nova 接收请求之前你是不需要添加额外的授权的。然而,如果你想要提供给客户或者大型开发团队去访问你的客户端时,你可能希望对某些请求加上权限。例如,只希望管理员可以删除记录。值得高兴的是,Nova 提供了一种简单的授权方法,这种方法正如你所了解的 Laravel 中的许多功能一样。
## 策略
为了限制用户的哪些用户可以查看、创建、更新、或者删除资源,Nova 利用了 Laravel [授权策略](https://learnku.com/docs/laravel/5.6/authorization#creating-policies),策略是一个用于管理特定模型或者资源授权逻辑的简单类。例如,如果你的程序是一个博客,你可能有一个 `Post` 模型和相应的 `PostPolicy` 在你的程序中。
在 Nova 中操作资源时, Nova 会自动的尝试为模型找相应的策略。通常,这些策略会在你应用程序的 `AuthServiceProvider` 中注册。如果Nova 监测到你已经为模型注册了策略,他将在执行各自的操作前,自动检查该策略的相关授权方法,例如:
- `viewAny`
- `view`
- `create`
- `update`
- `delete`
- `restore`
- `forceDelete`
不需要额外的配置!例如,要确定允许哪些用户能够更新 `Post` 模型,你只需在相应的策略类上定义一个 `update` 方法:
```php
type == 'editor';
}
}
```
> **未定义策略方法**
> 如果策略存在但缺少特定的操作方法的策略,所有用户将不会被允许执行相应的操作的,所以,当你已经定义策略后,请定义其所有的相关授权方法。
### 隐藏实体资源
如果你希望对你的用户隐藏一个 Nove 的实体资源,你可以定义一个 `viewAny` 方法在对应模型的策略类上。如果在该模型的策略类上没有 `viewAny` 方法,Nova 认为所有用户都能查看该资源:
```php
permissions);
}
}
```
### 模型关系
我们已经学会了怎样授权简单的视图、创建、更新和删除动作,但是模型关系的交互呢?例如,如果你希望建立一个播客程序,你希望某些特定的 Nova 用户可以给播客评论。同样的,Nova 使用了 Laravel 的策略简单的实现。
使用模型关系时,Nova 使用了简单的命名规则。为了简单的说明这个规则,让我们假设你的程序具有 `Podcast` 资源和 `Comment` 资源。如果你希望某个授权的用户能够给一篇播客添加评论,你应该在播客模型的策略类里定一个 `addComment` 方法:
```php
**多对多的授权**
>在处理多对多的关系时, 请确保在每个涉及的资源的策略类上定义适当的授权策略方法。
### 禁用授权
如果你的某个 Nova 的资源模型已经有相应的策略,但是你希望禁用该资源的 Nova 授权,我们可以覆盖 `authorizable` Nova 资源策略类的方法:
```php
/**
* 定义该资源策略是否启用
*
* @return bool
*/
public static function authorizable()
{
return false;
}
```
## 字段
有时候,你可能希望对某些用户组隐藏某些字段。你可以通过 `canSee` 方法链接到字段的定义,轻松完成这个操作。`canSee` 该方法接收一个返回 `true` 或 `false` 的一个闭包函数。然而这个闭包函数接收HTTP的请求对象作为参数:
```php
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
/**
* 获取资源显示的字段。
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function fields(Request $request)
{
return [
ID::make()->sortable(),
Text::make('Name')
->sortable()
->canSee(function ($request) {
return $request->user()->can('viewProfile', $this);
}),
];
}
```
上面的例子中,我们在`User`模型里使用 Laravel 的`Authorizable` trait 的`can`方法,来确定授权用户是否被授权`viewProfile`动作。然而,由于代理授权策略方法是`canSee`的常见用例,你可以使用`canSeeWhen`方法实现相同的行为。`canSeeWhen`方法与`Illuminate\Foundation\Auth\Access\Authorizable`trait 的`can`方法有相同的方法签名:
```php
Text::make('Name')
->sortable()
->canSeeWhen('viewProfile', $this),
```
> **授权 & 「can」方法**
> 想了解更多关于 Laravel 授权和`can`方法的信息,请查看完整的 Laravel [授权文档](https://laravel.com/docs/5.6/authorization#via-the-user-model) 。
## 可关联过滤
如果你希望过滤数据在关联数据中的展示,你可以在 Nova 资源中覆盖 `relatableQuery` 方法。
例如,如果你的项目中有一个 `Comment` 资源属于一个 `Podcast` 资源。在创建一个 `Comment` 资源时,Nova 将允许你选择他归属的 `Podcast` 资源。为了在选项中限制用户能选择的 `Podcast`,你应该在`Podcast`资源中覆盖 `relatableQuery` 方法:
```php
/**
* 为资源构建可关联过滤。
*
* 这个查询条件决定了哪些实例可以在关联选项中被选择。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function relatableQuery(NovaRequest $request, $query)
{
return $query->where('user_id', $request->user()->id);
}
```
## Scout 过滤
如果你的应用程序使用了强大的Laravel Scout[搜索](https://learnku.com/docs/laravel/5.6/scout/1417)扩展,你可以自定义 `Laravel\Scout\Builder` 查询实例,然后将其提供个查询服务提供者。如果你要完成这个操作,请复写你资源上的 `scoutQuery` 方法
```php
/**
* 为给定的资源构建一个 Scout 搜索查询。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Laravel\Scout\Builder $query
* @return \Laravel\Scout\Builder
*/
public static function scoutQuery(NovaRequest $request, $query)
{
return $query->where('user_id', $request->user()->id);
}
```