Yii2中最简单的基础认证——IdentityInterface的实现
The most simple basic authentication in Yii2 - implementation of IdentityInterface
我想将 HTTP 基本身份验证添加到我的 Yii2 应用程序中,其中 username/password 存储在 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;
}
},
],
];
}
我需要创建 class,它实现了 IdentityInterface,这就是为什么我有 class:
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;
}
}
很好,应用程序在第一个请求的情况下要求 username/password,但随后它设法以某种方式将身份验证存储在某个内部会话中,并且不需要为每个新请求重复身份验证它是由浏览器(我的添加会话)生成的,还是由 Postman 生成的(当然不会保留会话)。是否可以修改用户 class 以要求为每个新请求提供用户名和密码?
我试过使用您的代码。
首先,您的代码足以要求基本身份验证成为每个请求的一部分。如果 Authorization
header 在请求中不存在,yii 将 return 401 Unauthorized
。所以您的实施已经在做您需要的事情了。
用户不必每次都输入username/password是有原因的。
对于网络浏览器:
为 session 保存凭据,浏览器将在每个后续请求中自动发送它们,而无需用户再次提示。
对于邮递员:只要您不手动删除授权设置,就会为请求存储授权,它将作为每个请求的一部分发送。
如果你想强制用户在每个请求中手动输入 username/password 你可以扩展 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;
}
}
但这需要 sessions 才能工作,因此它只能与浏览器一起使用。它不适用于 API。对于邮递员,此实现将使每个其他请求都失败并返回 401 Unauthorized
。对于将使用 cookie 的 api,它会以同样的方式失败,并且对于不适用于 cookie 的 api 的每个请求都会失败。
旁注:邮递员做 keep/send cookie,所以 sessions 与邮递员一起工作。
我想将 HTTP 基本身份验证添加到我的 Yii2 应用程序中,其中 username/password 存储在 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;
}
},
],
];
}
我需要创建 class,它实现了 IdentityInterface,这就是为什么我有 class:
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;
}
}
很好,应用程序在第一个请求的情况下要求 username/password,但随后它设法以某种方式将身份验证存储在某个内部会话中,并且不需要为每个新请求重复身份验证它是由浏览器(我的添加会话)生成的,还是由 Postman 生成的(当然不会保留会话)。是否可以修改用户 class 以要求为每个新请求提供用户名和密码?
我试过使用您的代码。
首先,您的代码足以要求基本身份验证成为每个请求的一部分。如果 Authorization
header 在请求中不存在,yii 将 return 401 Unauthorized
。所以您的实施已经在做您需要的事情了。
用户不必每次都输入username/password是有原因的。
对于网络浏览器: 为 session 保存凭据,浏览器将在每个后续请求中自动发送它们,而无需用户再次提示。
对于邮递员:只要您不手动删除授权设置,就会为请求存储授权,它将作为每个请求的一部分发送。
如果你想强制用户在每个请求中手动输入 username/password 你可以扩展 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;
}
}
但这需要 sessions 才能工作,因此它只能与浏览器一起使用。它不适用于 API。对于邮递员,此实现将使每个其他请求都失败并返回 401 Unauthorized
。对于将使用 cookie 的 api,它会以同样的方式失败,并且对于不适用于 cookie 的 api 的每个请求都会失败。
旁注:邮递员做 keep/send cookie,所以 sessions 与邮递员一起工作。