Dominus77 / yii2-advanced-start

Yii2 Start Project Advanced Template

Home Page:https://dominus77.github.io/yii2-advanced-start/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

auth_key is not guaranteed to be unique

zmoddynamics opened this issue · comments

Hello, thank you for creating this extension. In reviewing the code I see that you implement findIdentityByAccessToken in the BaseUser class.

php
// /users/models/BaseUser.php

    /**
     * @param mixed $token
     * @param mixed $type
     * @return yii\db\ActiveRecord
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        return static::findOne(['auth_key' => $token, 'status' => self::STATUS_ACTIVE]);
    }

I assume auth_key column in the user table is meant to be used for authorization (ie. when making rest API calls to the api module). Is that the intended use ? If so, what are your thoughts on the non-uniqueness of this parameter? It appears to be generated using:

php
// /users/models/BaseUser.php
    /**
     * Generates "remember me" authentication key
     * @throws Exception
     */
    public function generateAuthKey()
    {
        /** @var yii\base\Security $security */
        $security = Yii::$app->security;
        $this->auth_key = $security->generateRandomString();
    }

Although it is unlikely, my understanding is generateRandomString() is not guaranteed to be unique and thus may present a security risk (albeit it a small one). Curious as to your thoughts?

Hello! Yes, generating a not unique value is unlikely, but to ensure that it will be unique, in the rules of the User model, define attribute values as unique.

fb3e609

It is also possible to create a function that checks the model attribute for uniqueness, if the generated value is not unique, generate another, until get a unique value.

Yes. I would implement both approaches you suggest for completeness. The problem with just implementing it in dB schema and rules is that it may cause validation error or database error if it is not unique when you attempt the insert. By defining a function to continuously regenerate until the fields are unique you avoid that issue.

Added method generateUniqueRandomString() in BaseUser

public function generateUniqueRandomString($attribute, $maxIteration = 10)
{
$security = Yii::$app->security;
if ($attribute && $maxIteration > 0) {
$i = 0;
while($i <= $maxIteration) {
$string = $security->generateRandomString();
if ((static::findOne([$attribute => $string])) === null) {
return $string;
}
$i++;
}
throw new Exception('Failed to generate unique value, try increasing the number of iterations.');
}
return $security->generateRandomString();
}

How would you suggest I update my project to reflect these changes? composer update doesn't seem to do anything

That's right, because the project was installed as a project and not an extension.

Change the following points yourself:

/**
* Generates "remember me" authentication key
* @throws Exception
*/
public function generateAuthKey()
{
$this->auth_key = $this->generateUniqueRandomString('auth_key');
}

/**
* Generates email confirmation token
* @throws Exception
*/
public function generateEmailConfirmToken()
{
$this->email_confirm_token = $this->generateUniqueRandomString('email_confirm_token');
}

/**
* Generate Unique Random String
* @param string $attribute
* @param int $maxIteration
* @return string
* @throws Exception
*/
public function generateUniqueRandomString($attribute, $maxIteration = 10)
{
$security = Yii::$app->security;
if ($attribute && $maxIteration > 0) {
$i = 0;
while($i <= $maxIteration) {
$string = $security->generateRandomString();
if ((static::findOne([$attribute => $string])) === null) {
return $string;
}
$i++;
}
throw new Exception('Failed to generate unique value, try increasing the number of iterations.');
}
return $security->generateRandomString();
}

In order not to change it yourself, you need to fork my project into your repository, install a project for yourself from your repository, and get the latest updates from my repository for your own, then use git to update your project on the local machine.

See more: https://help.github.com/en/github/getting-started-with-github/fork-a-repo