当前位置: 首页 > 后端技术 > PHP

Yii2.0RESTfulAPI认证教程

时间:2023-03-29 15:46:02 PHP

认证介绍与web应用不同,RESTfulAPI通常是无状态的,这意味着不应使用session或cookie,因此每个请求都应该附带某种授权凭证,因为用户授权的状态可能无法通过会话或cookie来维护。通常的做法是为每个请求发送一个秘密访问令牌以对用户进行身份验证。由于访问令牌可以唯一标识和验证用户,因此API请求应通过HTTPS以防止中间人(MitM)中间人攻击。认证方式HTTP基本认证:accesstoken作为用户名发送,适用于accesstoken可以安全存在于API客户端的场景。例如,API客户端是一个运行在服务器上的程序。请求参数:accesstoken作为APIURL请求参数发送,如https://example.com/users?access-token=xxxxxxxx,由于大部分服务器都会将请求参数保存到日志中,该方式应该主要用于JSONPrequests,因为它不能使用HTTPheader来发送accesstokenOAuth2:用户从认证服务器获取基于OAuth2协议的accesstoken,然后通过HTTPBearerTokens发送给APIserver。以上是简单介绍,内容来自YiiFramework2.0权威指南。我们都知道Yii2.0默认的认证类是User,前后端共享同一个认证类。因此,我们需要单独分离出API认证类来实现前端。,后面,和API分离,接上一章:(这里暂时使用默认的User数据表,正式环境请分离不同的数据表进行认证)准备条件接上一篇User数据表,我们还需要要添加access_token字段,请直接在数据库中添加access_token字段。使用数据迁移进入项目根目录打开控制台输入以下命令:phpyiimigrate/createadd_access_token_to_user打开你的项目目录/console/migrations/m180704_054630_add_access_token_to_user.php修改以下内容:publicfunctionsafeUp(){$this->addColumn('user','access_token',$this->string());}publicfunctionsafeDown(){$this->dropColumn('user','access_token');}执行迁移命令phpyiimigratebrowseropen在frontend目录frontend页面,点击RegisterAccount,先注册一个账号配置打开api\config\main.php配置用户应用组件:*设置`identityClass`属性为whichauthenticationclass*设置`enableSession`属性为`false`*设置`enableAutoLogin`属性为`true`,注释掉session组件,或者删除'user'=>['identityClass'=>'api\models\User','enableAutoLogin'=>true,'enableSession'=>false,//'identityCookie'=>['name'=>'_identity-backend','httpOnly'=>true],],//'session'=>[//这是用于在后端登录的会话cookie的名称//'name'=>'advanced-backend',//】,编写api\models\User.php实现认证类,继承IdentityInterface,将common\models\User类复制到api\models\目录下,修改命名空间为api\modelsvalidate()){$access_token=$this->_user->generateAccessToken();}$this->_user->save();返回$access_token;}else{返回错误;}}上面的代码给User模型添加了一个generateAccessToken()方法,所以我们把这个方法添加到api\models\User.php命名空间api\models;useYii;useyii\base\NotSupportedException;useyii\behaviors\TimestampBehavior;使用yii\db\ActiveRecord;使用yii\web\IdentityInterface;...类用户扩展ActiveRecordcordimplementsIdentityInterface{....../***生成accessToken字符串*@returnstring*@throws\yii\base\Exception*/publicfunctiongenerateAccessToken(){$this->access_token=Yii::$app->安全->generateRandomString();返回$this->access_token;}}接下来打开之前的User控制器,写登录方法useapi\models\LoginForm;......//省略部分代码/***Login*@returnarray*@throws\yii\base\Exception*@throws\yii\base\InvalidConfigException*/publicfunctionactionLogin(){$model=newLoginForm();if($model->load(Yii::$app->getRequest()->getBodyParams(),'')&&$model->login()){return['access_token'=>$model->login(),];}else{return$model->getFirstErrors();}}...最后添加一条新的URL规则,打开api\config\main.php,修改components属性,添加如下代码:'urlManager'=>['enablePrettyUrl'=>true,'enableStrictParsing'=>真,'showScriptName'=>false,'rules'=>[['class'=>'yii\rest\UrlRule','controller'=>'user','extraPatterns'=>['POSTlogin'=>'login',],],],]使用调试工具测试http://youdomain/users/login记住是POST请求发送,如果POSTMAN有问题,请指定Content-Type:application/x-www-form-urlencodedok,如果不出意外,相信你已经可以收到一个access_token了。下一步是如何使用此令牌以及如何维护身份验证状态。如果您不携带此令牌,您将无法访问。只需要两步就可以返回401,维持认证状态。:在REST控制器类中配置身份验证器行为以指定要使用的身份验证方法。在您的用户身份类中实现yiiwebIdentityInterface::findIdentityByAccessToken()-detail)方法。接下来,我们围绕这两个步骤来实现:添加一个RESTcontroller因为我这里没有设计其他的数据表,所以我们暂且使用User数据表。在api\controllers\中添加一个新的控制器,命名为ArticleController并继承自yii\rest\ActiveController。配置认证方式代码:代码如下:CompositeAuth::className(),'authMethods'=>[HttpBasicAuth::className(),HttpBearerAuth::className(),QueryParamAuth::className(),],];返回$行为;注意:这个controller不是真正的Article,而是User实现了findIdentityByAccessToken()方法:打开api\models\User。php重写了findIdentityByAccessToken()方法......classUserextendsActiveRecordimplementsIdentityInterface{......publicstaticfunctionfindIdentityByAccessToken($token,$type=null){returnstatic::findOne(['access_token'=>$代币]);}...}为新添加的controller添加路由规则(ps:好像多了一步...)修改api\config\main.php'urlManager'=>['enablePrettyUrl'=>true,'enableStrictParsing'=>true,'showScriptName'=>false,'rules'=>[['class'=>'yii\rest\UrlRule','controller'=>'user','extraPatterns'=>['GETsend-email'=>'send-email''POSTlogin'=>'login',],],['class'=>'yii\rest\UrlRule','controller'=>'article','extraPatterns'=>[],],],]接下来访问你的域名http://youdomain/articles,是不是不带参数返回401?ok,这里介绍两种访问方式,一种是URL访问,一种是通过header携带http://youdomain/articles?acc...。Authorization:Bearery3XWtwWaxqCEBDoE-qzZk0bCp3UKO920注意Bearer和你的token中间有一个空格。很多同学都摸过很多次。YII2.0RESTful认证结束。更完整的功能请移步官方文档进行授权验证。还有就是速度验证,自己找吧另外,不懂的,或者写的不好的,请移步维希老师的视频教程。我所有的内容都是跟魏曦老师学的。维希教你写完认证后发现我们接口返回的数据不是很直观,现实生活中通常不是这样的。我们可能会返回一些特定的格式来自定义响应内容。打开api\config\main.php并在components数组中添加以下内容。'response'=>['class'=>'yii\web\Response','onbeforeSend'=>function($event){$response=$event->sender;$response->data=['success'=>$response->isSuccessful,'code'=>$response->getStatusCode(),'message'=>$response->statusText,'data'=>$response->数据,];$response->statusCode=200;},],这里的状态码统一设置为200,具体配置可以单独配置。如果登录操作密码错误或其他,我们可以在controller中这样使用:$response=Yii::$app->response;$response->setStatusCode(422);return['errmsg'=>'用户名或密码错误!'];水平有限,难免有错误,望指教,不胜感激