yii2中使用rest的方法和正常的项目目录接口没什么太大区别有几处需要注意的是
1、在controller创建的时候继承的类由一般web项目的yii\web\Controller换成yii\rest\Controller,但是一般会使用中间类继承yii\rest\Controller,以便重写相关函数的处理,假设类名为ApiController;
2、在ApiController类中重写init函数,enableSession设置为false:
public function init()
{
parent::init();
\Yii::$app->user->enableSession = false;
}
3、关于接口登录态验证的变化,web项目的action的登录态验证直接是在behaviors函数中控制的。如下:
/**
* @inheritdoc
*/
public function behaviors()
{
return [
'verbs' => [
'class' => yii\filters\VerbFilter::className(),
'actions' => [
],
],
'access' => [
'class' => yii\filters\AccessControl::className(),
'rules' => [
[
'allow' => true,
'actions' => [''],//页面访问不需要的登录态验证的
'roles' => ['?'],
],
[
'allow' => true,
'actions' => [ 'view','update','create'],//页面访问需要登录态验证的
'roles' => ['@'],
],
],
],
];
}
rest框架中使用的登录态的认证虽然也是behaviors函数中完成的,但是验证的函数以及方式不同的,web项目的登录态验证通常使用的是session验证的机制,但是rest一般使用的是token验证的方法,登录成功返回给客户端存在本地,客户端每次访问接口的时候再带过来,具体的形式有三种QueryParamAuth、HttpBearerAuth、HttpBasicAuth,这里举例HttpBearerAuth简单验证版,重写以后的类为LHttpBearerAuth,behaviors函数如下(举例用户模块):
public function behaviors()
{
return ArrayHelper::merge(parent::behaviors(), [
'authenticator' => [
'authMethods' =>[
LHttpBearerAuth::className(), // 默认需要登录态验证
],
'except' => [ // 添加不需要登录态验证的接口
'login',
'sign-up',
'find-pwd',
'reset-pwd',
],
],
'verbFilter' => [
'class' => yii\filters\VerbFilter::className(),
'actions' =>[
'login' => ['POST','OPTIONS'],
],
],
] );
LHttpBearerAuth类如下:
class LHttpBearerAuth extends HttpBearerAuth
{
/**
* @inheritdoc
*/
public function authenticate($user, $request, $response)
{
if ($request->isOptions) // 搭配前端vue跨域请求使用处理cors的预请求
{
$response->statusCode = 200;
\Yii::$app->end();
}else{
$authHeader = $request->getHeaders()->get('Authorization');
if ($authHeader !== null && preg_match("/^Bearer\\s+(.*?)$/", $authHeader, $matches)) {
$identity = $user->loginByAccessToken($matches[1], get_class($this));
if ($identity === null) {
$this->handleFailure($response);
}
return $identity;
}
}
return null;
}
/**
* @inheritdoc
*/
public function handleFailure($response)
{
ApiController::exceptionToCode(array(
"retCode" => XXX
"retMsg" => XXX,
"retData" => [],
));
}
}
前端访问接口的时候需要传入header参数Authorization为XXXXXXX(此处应与解析的规则一致即可)
主要目录如下: