【问题标题】:Authenticating against two different database tables针对两个不同的数据库表进行身份验证
【发布时间】:2015-06-03 03:54:31
【问题描述】:

我对 Yii 2.0 中的身份验证过程有点困惑。我正在开发一个具有两种用户(学生和讲师)的 Web 应用程序。每个实体都有自己的数据库表(如果重要的话是 MySQL)和自己的 id、用户名和密码字段。我查看了包含针对数据库的身份验证的高级应用程序模板,但在这种情况下,用户表是唯一的。就我而言,我必须能够确定要查找用户记录(学生或讲师)的数据库表。身份界面:

interface IdentityInterface
{
    /**
    * Finds an identity by the given ID.
    * @param string|integer $id the ID to be looked for
    * @return IdentityInterface the identity object that matches the given ID.
    * Null should be returned if such an identity cannot be found
    * or the identity is not in an active state (disabled, deleted, etc.)
    */
    public static function findIdentity($id);
    /**
    * Finds an identity by the given token.
    * @param mixed $token the token to be looked for
    * @param mixed $type the type of the token. The value of this parameter depends on the implementation.
    * For example, [[\yii\filters\auth\HttpBearerAuth]] will set this parameter to be `yii\filters\auth\HttpBearerAuth`.
    * @return IdentityInterface the identity object that matches the given token.
    * Null should be returned if such an identity cannot be found
    * or the identity is not in an active state (disabled, deleted, etc.)
    */
    public static function findIdentityByAccessToken($token, $type = null);
    /**
    * Returns an ID that can uniquely identify a user identity.
    * @return string|integer an ID that uniquely identifies a user identity.
    */
    public function getId();
    /**
    * Returns a key that can be used to check the validity of a given identity ID.
    *
    * The key should be unique for each individual user, and should be persistent
    * so that it can be used to check the validity of the user identity.
    *
    * The space of such keys should be big enough to defeat potential identity attacks.
    *
    * This is required if [[User::enableAutoLogin]] is enabled.
    * @return string a key that is used to check the validity of a given identity ID.
    * @see validateAuthKey()
    */
    public function getAuthKey();
    /**
    * Validates the given auth key.
    *
    * This is required if [[User::enableAutoLogin]] is enabled.
    * @param string $authKey the given auth key
    * @return boolean whether the given auth key is valid.
    * @see getAuthKey()
    */
    public function validateAuthKey($authKey);
}

包含findIdentity() 方法,不幸的是它是静态的。我这样说是因为我无法传递额外的参数或从实现此接口的app\models\User 类访问实例变量,这将区分用于用户身份验证的数据库表。在我的例子中,findIdentity() 中的 $id 参数不是唯一的。

我该如何找到解决方案?

【问题讨论】:

  • studentslecturers 表的结构是完全不同的吗?也许只是使用公用表userstype 列?如果需要,您可以为它们使用不同的模型。 stackoverflow.com/questions/29167761/… 否则,我认为您应该使用覆盖框架类(负责该问题)来解决此问题,因为它是不常见且广泛使用的方法。
  • 我想这将是一个解决方案,为所有用户使用相同的表,因为两者都包含基本字段(id、用户名、密码)并且每个用户类型字段都有不同的表。但我想要一个比这更干净的解决方案。我将如何对两个不同的表实施身份验证?
  • 我的意思是非广泛的方法。

标签: php yii2


【解决方案1】:

我看到了 3 个选项:

1) 如果studentslecturers 表的结构没有绝对不同,也许最好使用公共表userstype 列。如果需要,您可以为它们使用不同的模型(请参阅here)。

2) 由于它是不常见且不广泛使用的方法,因此您可以覆盖核心类。

使用不同的命名空间创建 IdentityInterface 的副本,并更改​​ findIdentity() 声明以满足您的需求。然后使用您的自定义界面而不是内置界面。

除了User 模型不要忘记搜索所有框架类以查找findIdentity() 的用法并将其替换为您的实现。

正如我所见,它仅在 loginByCookie()renewAuthStatus() 受保护的方法中在 yii\web\User 中调用。

也覆盖这个类,然后将user 组件配置中的类切换到您的自定义配置。

3) 以其他方式传递附加参数。例如Yii::$app->params。不过,这似乎是一个黑客解决方案。

我个人建议使用第一种或第三种方法(以防您反对使用第一种)。

【讨论】:

  • 经过更多考虑,解决方案 1 是要走的路。谢谢。
  • 我认为你的选择是正确的,在我看来确实更好。
  • 您能否提供一个关于解决方案 2 的示例?
  • 您到底需要知道什么?我试图提及该方法的所有重要细节。
  • 如果我尝试创建一个扩展 yii\web\IdentityInterface 的新接口并尝试覆盖 findIdentity() 静态方法,如果我尝试添加新参数,我会收到 PHP 错误:Declaration must be compatible with IdentityInterface::findIdentity(id : int|string)。由于此方法是静态的,因此我无法以非静态方式引用接口变量,这就是我猜的问题。有什么建议吗?
猜你喜欢
  • 2017-06-14
  • 1970-01-01
  • 2011-06-10
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-07
  • 2019-10-24
相关资源
最近更新 更多