阿江 2017-10-15 09:13:02 3290次浏览 0条回复 0 0 0

说明

学习Yii Framework 2易2框架的过程是漫长的也是充满乐趣的以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现提供了较完整的代码供你参考不妥之处请多多指正

原文网址:

http://www.yiiframework.com/doc-2.0/guide-rest-authentication.html

本文主题:RESTful的用户验证(Authentication)

与Web应用不同,RESTful API通常是无状态的,也就是说session和cookie将不能被使用。因为用户状态无法由session或cookie维护,所以,每次请求都需要携带某种用户验证凭证。通行做法是为每个请求发送一个加密的存取令牌用于验证用户身份。因为一个存取令牌可以唯一标识和认证一个用户,API请求通常使用HTTPS来发送,以防止MitM攻击(man-in-the-middle)。

有以下几种方法去发送一个存取口令: 1、HTTP基础认证:发送用户名作为存取令牌,这种情况使用在存取令牌可以被安全存储在API消费者端时,例如,API消费者是一个运行在服务器上的程序。 2、查询参数:存取令牌使用API URL的一个查询参数的方式发送,例如,https://example.com/users?access-token=xxxxx。因为大多数的Web服务器将保存查询参数在服务器日志中,所以此方法主要使用在提供JSONP请求,也就是不能使用HTTP头令牌发送存取令牌。 3、OAuth 2:遵照OAuth2协议,存取令牌从认证服务器的消费者中获取,并使用HTTP Bearer Tokens发送到API服务器。 HTTP Bearer Tokens: https://tools.ietf.org/html/rfc6750

Yii支持以上所有的认证方法,你也可以自行创建一个新的认证方法。

要使API的认证有效,可以遵照以下步骤: 1、配置user应用组件: 1)设置enableSession属性为false 2)设置loginUrl属性为null显示HTTP403错误,而不是跳转到登录页面。 2、在REST控制器类中配置authenticator行为定义你准备使用的验证方法。 3、在用户标识类(user identity class)中实现yii\IdentityInterface::findIdnetityByAccessToken()

因为RESTful API是无状态的,所以第1步虽非必须,但推荐如此操作。当enableSession是false时,用户认证状态将不会使用请求的session状态来保持,相反的,通过第2步和第3步将为每个请求去执行认证。

小贴士: 如果你是以应用的方式开发RESTful API,你可以在应用配置中配置user应用组件的enableSession。如果你以模块的方式开发RESTful API,你可以将以下代码放置在模块的init()方法中:

public function init(){
	parent::init();
	\Yii::$app->user->enableSession=false;
}

例如,要使用HTTP基本认证,你可以配置authenticator行为,代码如下:

use yii\filters\auth\HttpBasicAuth;
public function behaviors(){
	$behaviors=parent::behaviors();
	$behaviors['authenticator']=[
		'class'	=>HttpBasicAuth::className(),
	];
	return $behaviors;
}

如果你想要支持以上三种认证方法,你可以使用CompositeAuth,代码如下:

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(),
		],
	];
}

在authMethods中每个元素是一个认证方法类名或一个配置数组。 findIdnetityByAccessToken()的实现是应用的特征,例如,在每个用户只能使用一个存取令牌的简单场景中,你可以在用户表的access_token列中存储存取令牌,此方法可以在User类中轻松实现,代码如下:

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取回。 如果认证失败,HTTP401状态的响应将和其他头信息(如HTTP基础认证的WWW-Authenticate头信息)一起被发送回来。

Authorization(用户授权)

在一个用户被验证后,你可能需要检查它是否具有针对请求资源的请求执行动作的许可,此过程被称为授权(authorization),祥情请参考Authorization章节: http://www.yiiframework.com/doc-2.0/guide-security-authorization.html

如果你的控制器继承自yii\rest\ActiveController,你可以重写checkAccess()方法来执行认证检查,此方法将调用yii\rest\ActiveController的内置动作。

(全文完)

    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册