我想向我的Yii2应用程序添加HTTP基本身份验证,其中用户名/密码存储在Yii配置文件中-对于一个用户,没有数据库身份验证。
我已经通过添加behaviors
功能为我的控制器启用了身份验证:
public function behaviors()
{
return [
'basicAuth' => [
'class' => \yii\filters\auth\HttpBasicAuth::className(),
'auth' => function ($username, $password) {
if ($username=='api') {
return new SimpleApiUser();
} else {
return null;
}
},
],
];
}
而且我被要求创建实现IdentityInterface的类,这就是我拥有类的原因:
class SimpleApiUser implements IdentityInterface {
public static function findIdentity($id)
{
return null;
}
public static function findIdentityByAccessToken($token, $type = null)
{
return null;
}
public function getId()
{
return 1;
}
public function getAuthKey()
{
return 1;
}
public function validateAuthKey($authKey)
{
return true;
}
}
很好,在第一个请求的情况下,应用程序会要求输入用户名/密码,但是随后它设法以某种方式在内部会话中存储了身份验证,并且不需要对每个新请求进行重复身份验证,因为它是由浏览器(我添加会话的浏览器)还是Postman(当然不保留会话)的浏览器。是否可以修改用户类别以要求在每个新请求中都提供用户名和密码?
我已经尝试过使用您的代码了。
首先,您的代码足以要求基本身份验证成为每个请求的一部分。如果请求中不存在Authorization
标头,则yii将返回401 Unauthorized
。因此,您的实现已经在执行所需的操作。
出于某些原因,不需要用户每次输入用户名/密码。
对于网络浏览器:保存凭据以进行会话,浏览器将在随后的每个请求中自动发送它们,而无需再次提示用户。
对于邮递员:授权存储在请求中,只要您不手动删除授权设置,它将作为每个请求的一部分发送。
如果要强制用户在每个请求中手动输入用户名/密码,则可以扩展HttpBasicAuth组件以假装授权不是其他所有请求的请求的一部分,例如这样
use Yii;
use yii\filters\auth\HttpBasicAuth;
class MyHttpBasicAuth extends HttpBasicAuth
{
const SESSION_KEY = 'authForced';
private $session;
public function __construct($config = [])
{
parent::__construct($config);
$this->session = Yii::$app->session;
}
public function authenticate($user, $request, $response)
{
if ($this->session->has(self::SESSION_KEY)) {
$this->session->remove(self::SESSION_KEY);
return parent::authenticate($user, $request, $response);
}
$this->session->set(self::SESSION_KEY, true);
return null;
}
}
但是这需要会话才能正常工作,因此只能与浏览器一起使用。它不适用于API。对于邮递员,此实现将使其他所有请求均失败,并带有401 Unauthorized
。对于将与cookie一起使用的api,将以相同的方式失败,并且将对与cookie一起使用的api的每个请求均将失败。
附带说明:邮递员会保留/发送cookie,因此会话可与邮递员一起使用。