yii2-restful的全局认证和局部认证的接口设置

来源:互联网 发布:linux 文件删不掉原因 编辑:程序博客网 时间:2024/05/23 11:04
yii2在使用restful作为接口的时候,yii\rest\Controller中已经把全局的csrf验证设置为false,

public $enableCsrfValidation = false;

也就是在post数据的时候,不会在进行_csrf参数的验证。

那么在开发restful接口的时候,比如一个app的服务端restful接口,用户分为游客和登录用户,一开始,游客打开这个app的时候,他并没有登录,只是游客身份来访问,那么这时候,app的页面必须的有内容显示,这些内容就是通过restful接口返回的json数据。

所以这些不需要token认证的restful接口就必须设置可以直接访问内容,无需认证,当然这也就是权限设置。

当一个游客点击app的一个tag,例如“我”,那么对于关于“我”的这个接口,在服务端肯定是要判断用户是否登录了,这个接口只有登录用户才能使用,所以就需要进行token的认证。

总的来说,也就是一些restful接口请求的内容呢,公共开放的内容不管是什么身份,只要访问了都可以有权限访问,不需认证。而对于一些属于私人的内容呢,就必须要登录了,通过认证了才能访问。

在yii2的restful中,我们可以设置三种安全认证的方式,参考:
http://www.yiichina.com/doc/guide/2.0/rest-authentication

第一种情况, 使用 HTTP Basci Auth

use yii\helpers\ArrayHelper;use yii\filters\auth\HttpBasicAuth;public function behaviors(){$parent = parent::behaviors();    $parent['authenticator'] => [        'class' => HttpBasicAuth::className(),        /**        如果设置了这个auth,就会按照这个auth进行认证,可以查看yii\filters\auth\HttpBasicAuth源码,        如果没设置这个属性,那么就会使用access-tokend的方式实现,$username作为access-token,        使用main.php配置中的User组件类实现,而且User组件类类中必须设置loginByAccessToken()函数实现。        所以,如果使用HttpBasicAuth的话,强烈建议设置auth属性        */        'auth' => function ($username, $password) {        return \app\models\User::findOne([            'username' => $username,            'password' => $password,        ]);    }    ]}


第二种情况是access-token的方式

use yii\helpers\ArrayHelper;use yii\filters\auth\QueryParamAuth;public function behaviors(){ $parent = parent::behaviors();    $parent['authenticator'] => [                'class' => QueryParamAuth::className(),                // 设置token名称,默认是access-token                'tokenParam' => 'token'            ]}


下面看一下yii\filters\auth\QueryParamAuth的authenticate()

public function authenticate($user, $request, $response)    {        $accessToken = $request->get($this->tokenParam);        if (is_string($accessToken)) {            $identity = $user->loginByAccessToken($accessToken, get_class($this));            if ($identity !== null) {                return $identity;            }        }        if ($accessToken !== null) {            $this->handleFailure($response);        }        return null;    }

当我们请求的时候,将会获取到这个$accessToken = $request->get($this->tokenParam)的值。

然后调用$user->loginByAccessToken()这个组件的loginByAccessToken()去进行验证,$user也就是我们在配置文件中配置的认证的User组件,对应的class,在这里我设置的是api\models\User,也就是这个User类必须实现loginByAccessToken()这个函数,函数里面具体的业务自己定义了。

第三种方式就不说了。

当在一个restful的控制器中的

public function behaviors()  {

}

设置了以上的认证方式,那么就会开启整个认证,也就是访问这个控制器的每一个请求的action都会进行验证,也就是全局验证。

所以,根据上面说的一些业务,我们知道有一些内容,是任意用户都可以看的,不需要登录,不需要认证的,但现在问题是只要设置了认证方式,不管哪个restful接口请求都要认证,也就是全局认证,那怎么办?

对此,我们就必须能够在behaviors()进行一些设置,比如定义一些需要登录和认证的才能访问的函数action有哪些,然后与当前访问的操作action进行比较即可。

 function behaviors() {        $behaviors = parent::behaviors();                // 当前操作的id        $currentAction = Yii::$app->controller->action->id;        // 需要进行认证的action        $authActions = ['index'];        // 需要进行认证的action就要设置安全认证类        if(in_array($currentAction, $authActions)) {            $behaviors['authenticator'] = [                'class' => QueryParamAuth::className(),            ];        }        return ArrayHelper::merge([            //设置可以接收访问的域和方法。            [                'class' => Cors::className(),                'cors' => [                    'Origin' => ['*'],                    // 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],                    'Access-Control-Request-Headers' => ['Origin', 'X-Requested-With', 'Content-Type', 'Accept'],                    'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],                ],            ],        ], $behaviors);      }

就是按照以上的设置就可以,将你觉得需要认证的action放在$authActions的数组里即可。当请求的是这些设置需要认证的action的时候,就会返回401,代表没办法认证通过,需要认证。


1 0