forked from yiisoft/yii2
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request yiisoft#7132 from yii2-chinesization/master
Chinese Translation for last month
- Loading branch information
Showing
5 changed files
with
458 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
认证 | ||
============== | ||
|
||
和Web应用不同,RESTful APIs 通常是无状态的,也就意味着不应使用sessions 或 cookies, | ||
因此每个请求应附带某种授权凭证,因为用户授权状态可能没通过sessions 或 cookies维护, | ||
常用的做法是每个请求都发送一个秘密的access token来认证用户,由于access token可以唯一识别和认证用户, | ||
**API 请求应通过HTTPS来防止man-in-the-middle (MitM) 中间人攻击**. | ||
|
||
下面有几种方式来发送access token: | ||
|
||
* [HTTP 基本认证](http://en.wikipedia.org/wiki/Basic_access_authentication): access token | ||
当作用户名发送,应用在access token可安全存在API使用端的场景,例如,API使用端是运行在一台服务器上的程序。 | ||
* 请求参数: access token 当作API URL请求参数发送,例如 | ||
`https://example.com/users?access-token=xxxxxxxx`,由于大多数服务器都会保存请求参数到日志, | ||
这种方式应主要用于`JSONP` 请求,因为它不能使用HTTP头来发送access token | ||
* [OAuth 2](http://oauth.net/2/): 使用者从认证服务器上获取基于OAuth2协议的access token,然后通过 | ||
[HTTP Bearer Tokens](http://tools.ietf.org/html/rfc6750) 发送到API 服务器。 | ||
|
||
Yii 支持上述的认证方式,你也可很方便的创建新的认证方式。 | ||
|
||
为你的APIs启用认证,做以下步骤: | ||
|
||
1. 配置`user` 应用组件: | ||
- 设置 [[yii\web\User::enableSession|enableSession]] 属性为 `false`. | ||
- 设置 [[yii\web\User::loginUrl|loginUrl]] 属性为`null` 显示一个HTTP 403 错误而不是跳转到登录界面. | ||
2. 在你的REST 控制器类中配置`authenticator` 行为来指定使用哪种认证方式 | ||
3. 在你的[[yii\web\User::identityClass|user identity class]] 类中实现 [[yii\web\IdentityInterface::findIdentityByAccessToken()]] 方法. | ||
|
||
步骤1不是必要的,但是推荐配置,因为RESTful APIs应为无状态的,当[[yii\web\User::enableSession|enableSession]]为false, | ||
请求中的用户认证状态就不能通过session来保持,每个请求的认证通过步骤2和3来实现。 | ||
|
||
> 提示: 如果你将RESTful APIs作为应用开发,可以设置应用配置中 `user` 组件的[[yii\web\User::enableSession|enableSession]], | ||
如果将RESTful APIs作为模块开发,可以在模块的 `init()` 方法中增加如下代码,如下所示: | ||
|
||
```php | ||
public function init() | ||
{ | ||
parent::init(); | ||
\Yii::$app->user->enableSession = false; | ||
} | ||
``` | ||
|
||
例如,为使用HTTP Basic Auth,可配置`authenticator` 行为,如下所示: | ||
|
||
```php | ||
use yii\filters\auth\HttpBasicAuth; | ||
|
||
public function behaviors() | ||
{ | ||
$behaviors = parent::behaviors(); | ||
$behaviors['authenticator'] = [ | ||
'class' => HttpBasicAuth::className(), | ||
]; | ||
return $behaviors; | ||
} | ||
``` | ||
|
||
如果你系那个支持以上3个认证方式,可以使用`CompositeAuth`,如下所示: | ||
|
||
```php | ||
use yii\filters\auth\CompositeAuth; | ||
use yii\filters\auth\HttpBasicAuth; | ||
use yii\filters\auth\HttpBearerAuth; | ||
use yii\filters\auth\QueryParamAuth; | ||
|
||
public function behaviors() | ||
{ | ||
$behaviors = parent::behaviors(); | ||
$behaviors['authenticator'] = [ | ||
'class' => CompositeAuth::className(), | ||
'authMethods' => [ | ||
HttpBasicAuth::className(), | ||
HttpBearerAuth::className(), | ||
QueryParamAuth::className(), | ||
], | ||
]; | ||
return $behaviors; | ||
} | ||
``` | ||
|
||
`authMethods` 中每个单元应为一个认证方法名或配置数组。 | ||
|
||
|
||
`findIdentityByAccessToken()`方法的实现是系统定义的, | ||
例如,一个简单的场景,当每个用户只有一个access token, 可存储access token 到user表的`access_token`列中, | ||
方法可在`User`类中简单实现,如下所示: | ||
|
||
|
||
```php | ||
use yii\db\ActiveRecord; | ||
use yii\web\IdentityInterface; | ||
|
||
class User extends ActiveRecord implements IdentityInterface | ||
{ | ||
public static function findIdentityByAccessToken($token, $type = null) | ||
{ | ||
return static::findOne(['access_token' => $token]); | ||
} | ||
} | ||
``` | ||
|
||
在上述认证启用后,对于每个API请求,请求控制器都会在它的`beforeAction()`步骤中对用户进行认证。 | ||
|
||
如果认证成功,控制器再执行其他检查(如频率限制,操作权限),然后再执行操作, | ||
授权用户信息可使用`Yii::$app->user->identity`获取. | ||
|
||
如果认证失败,会发送一个HTTP状态码为401的响应,并带有其他相关信息头(如HTTP 基本认证会有`WWW-Authenticate` 头信息). | ||
|
||
|
||
## 授权 <a name="authorization"></a> | ||
|
||
在用户认证成功后,你可能想要检查他是否有权限执行对应的操作来获取资源,这个过程称为 *authorization* , | ||
详情请参考 [Authorization section](security-authorization.md). | ||
|
||
如果你的控制器从[[yii\rest\ActiveController]]类继承,可覆盖 [[yii\rest\Controller::checkAccess()|checkAccess()]] 方法 | ||
来执行授权检查,该方法会被[[yii\rest\ActiveController]]内置的操作调用。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
控制器 | ||
=========== | ||
|
||
在创建资源类和指定资源格输出式化后,下一步就是创建控制器操作将资源通过RESTful APIs展现给终端用户。 | ||
|
||
Yii 提供两个控制器基类来简化创建RESTful 操作的工作:[[yii\rest\Controller]] 和 [[yii\rest\ActiveController]], | ||
两个类的差别是后者提供一系列将资源处理成[Active Record](db-active-record.md)的操作。 | ||
因此如果使用[Active Record](db-active-record.md)内置的操作会比较方便,可考虑将控制器类 | ||
继承[[yii\rest\ActiveController]],它会让你用最少的代码完成强大的RESTful APIs. | ||
|
||
[[yii\rest\Controller]] 和 [[yii\rest\ActiveController]] 提供以下功能,一些功能在后续章节详细描述: | ||
|
||
* HTTP 方法验证; | ||
* [内容协商和数据格式化](rest-response-formatting.md); | ||
* [认证](rest-authentication.md); | ||
* [频率限制](rest-rate-limiting.md). | ||
|
||
[[yii\rest\ActiveController]] 额外提供一下功能: | ||
|
||
* 一系列常用操作: `index`, `view`, `create`, `update`, `delete`, `options`; | ||
* 对操作和资源进行用户认证. | ||
|
||
|
||
## 创建控制器类 <a name="creating-controller"></a> | ||
|
||
当创建一个新的控制器类,控制器类的命名最好使用资源名称的单数格式,例如,提供用户信息的控制器 | ||
可命名为`UserController`. | ||
|
||
创建新的操作和Web应用中创建操作类似,唯一的差别是Web应用中调用`render()`方法渲染一个视图作为返回值, | ||
对于RESTful操作直接返回数据,[[yii\rest\Controller::serializer|serializer]] 和 | ||
[[yii\web\Response|response object]] 会处理原始数据到请求格式的转换,例如 | ||
|
||
```php | ||
public function actionView($id) | ||
{ | ||
return User::findOne($id); | ||
} | ||
``` | ||
|
||
|
||
## 过滤器 <a name="filters"></a> | ||
|
||
[[yii\rest\Controller]]提供的大多数RESTful API功能通过[过滤器](structure-filters.md)实现. | ||
特别是以下过滤器会按顺序执行: | ||
|
||
* [[yii\filters\ContentNegotiator|contentNegotiator]]: 支持内容协商,在 [响应格式化](rest-response-formatting.md) 一节描述; | ||
* [[yii\filters\VerbFilter|verbFilter]]: 支持HTTP 方法验证; | ||
the [Authentication](rest-authentication.md) section; | ||
* [[yii\filters\AuthMethod|authenticator]]: 支持用户认证,在[认证](rest-authentication.md)一节描述; | ||
* [[yii\filters\RateLimiter|rateLimiter]]: 支持频率限制,在[频率限制](rest-rate-limiting.md) 一节描述. | ||
|
||
这些过滤器都在[[yii\rest\Controller::behaviors()|behaviors()]]方法中声明, | ||
可覆盖该方法来配置单独的过滤器,禁用某个或增加你自定义的过滤器。 | ||
例如,如果你只想用HTTP 基础认证,可编写如下代码: | ||
|
||
```php | ||
use yii\filters\auth\HttpBasicAuth; | ||
|
||
public function behaviors() | ||
{ | ||
$behaviors = parent::behaviors(); | ||
$behaviors['authenticator'] = [ | ||
'class' => HttpBasicAuth::className(), | ||
]; | ||
return $behaviors; | ||
} | ||
``` | ||
|
||
|
||
## 继承 `ActiveController` <a name="extending-active-controller"></a> | ||
|
||
如果你的控制器继承[[yii\rest\ActiveController]],应设置[[yii\rest\ActiveController::modelClass||modelClass]] 属性 | ||
为通过该控制器返回给用户的资源类名,该类必须继承[[yii\db\ActiveRecord]]. | ||
|
||
|
||
### 自定义操作 <a name="customizing-actions"></a> | ||
|
||
[[yii\rest\ActiveController]] 默认提供一下操作: | ||
|
||
* [[yii\rest\IndexAction|index]]: 按页列出资源; | ||
* [[yii\rest\ViewAction|view]]: 返回指定资源的详情; | ||
* [[yii\rest\CreateAction|create]]: 创建新的资源; | ||
* [[yii\rest\UpdateAction|update]]: 更新一个存在的资源; | ||
* [[yii\rest\DeleteAction|delete]]: 删除指定的资源; | ||
* [[yii\rest\OptionsAction|options]]: 返回支持的HTTP方法. | ||
|
||
所有这些操作通过[[yii\rest\ActiveController::actions()|actions()]] 方法申明,可覆盖`actions()`方法配置或禁用这些操作, | ||
如下所示: | ||
|
||
```php | ||
public function actions() | ||
{ | ||
$actions = parent::actions(); | ||
|
||
// 禁用"delete" 和 "create" 操作 | ||
unset($actions['delete'], $actions['create']); | ||
|
||
// 使用"prepareDataProvider()"方法自定义数据provider | ||
$actions['index']['prepareDataProvider'] = [$this, 'prepareDataProvider']; | ||
|
||
return $actions; | ||
} | ||
|
||
public function prepareDataProvider() | ||
{ | ||
// 为"index"操作准备和返回数据provider | ||
} | ||
``` | ||
|
||
请参考独立操作类的参考文档学习哪些配置项有用。 | ||
|
||
|
||
### 执行访问检查 <a name="performing-access-check"></a> | ||
|
||
通过RESTful APIs显示数据时,经常需要检查当前用户是否有权限访问和操作所请求的资源, | ||
在[[yii\rest\ActiveController]]中,可覆盖[[yii\rest\ActiveController::checkAccess()|checkAccess()]]方法来完成权限检查。 | ||
|
||
```php | ||
/** | ||
* Checks the privilege of the current user. 检查当前用户的权限 | ||
* | ||
* This method should be overridden to check whether the current user has the privilege | ||
* to run the specified action against the specified data model. | ||
* If the user does not have access, a [[ForbiddenHttpException]] should be thrown. | ||
* 本方法应被覆盖来检查当前用户是否有权限执行指定的操作访问指定的数据模型 | ||
* 如果用户没有权限,应抛出一个[[ForbiddenHttpException]]异常 | ||
* | ||
* @param string $action the ID of the action to be executed | ||
* @param \yii\base\Model $model the model to be accessed. If null, it means no specific model is being accessed. | ||
* @param array $params additional parameters | ||
* @throws ForbiddenHttpException if the user does not have access | ||
*/ | ||
public function checkAccess($action, $model = null, $params = []) | ||
{ | ||
// 检查用户能否访问 $action 和 $model | ||
// 访问被拒绝应抛出ForbiddenHttpException | ||
} | ||
``` | ||
|
||
`checkAccess()` 方法默认会被[[yii\rest\ActiveController]]默认操作所调用,如果创建新的操作并想执行权限检查, | ||
应在新的操作中明确调用该方法。 | ||
|
||
> 提示: 可使用[Role-Based Access Control (RBAC) 基于角色权限控制组件](security-authorization.md)实现`checkAccess()`。 |
Oops, something went wrong.