8000 user email verification token improvement · Issue #33 · leafsphp/auth · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
user email verification token improvement #33
Open
@systemmind

Description

@systemmind

I made user verification process like it was described in the tutorial.

When user registered the verification token is generated and is sent to the user email. At this time user continue to be logged in. When user click on the link received in the email an appropriate controller executed that contains the next code (like it was shown in tutorial):

$token = request()->get('token');
$isValid = auth()->verifyToken($token);

if ($isValid && auth()->user()->verifyEmail()) {
  // Email is verified
} else {
  // Could not verify email, missing or invalid token
}

This approach has some pitfall.

Consider the next example.

User 1 registers with email_1. The server sends verification link with token to the email_1.
User 2 registers with email_2. The server sends verification link with token to the email_2.

User 2 copy link from email_2, insert this link the web browser of the user 1 and press Enter.

In this case User 1 will be verified by the link of the user 2 that is incorrect.

Why it happens? Because the if operator if ($isValid && auth()->user()->verifyEmail()) { does not check that authorized user is the same user extracted from the verification token. We must check that. But to do this we must extract user.id from the verification token. And it is not good because it is already extracted in the verifyToken() function.

How I fixed this?

  1. In the vendor/leafs/auth/src/Auth.php file in the function verifyToken() I return $user instead true:
            if ($user->email !== $decodedToken['user.email']) {
                $this->errorsArray['token'] = 'Invalid token';
                return null;
            }

            # return true;
            return $user;
        } catch (\Throwable $th) {
            $this->errorsArray['token'] = $th->getMessage();
            return null;
        }
  1. I modified server controller behavior to check the user.id too:
        $token = request()->get('token');
        $user = auth()->verifyToken($token);
        if ($user && $user->id == auth()->user()->id() && auth()->user()->verifyEmail())
        {
          // Email is verified
        }
        else
        {
          // Could not verify email, missing or invalid token
        }

I think this is not the best solution. Maybe we must pass user.id to the verifyToken() function instead, for example:

$token = request()->get('token');
$isValid = auth()->verifyToken($token, auth()->user()->id());

if ($isValid && auth()->user()->verifyEmail()) {
  // Email is verified
} else {
  // Could not verify email, missing or invalid token
}

and check does this user.id corresponds to the user.id of the token inside verifyToken().

Anyway this is what may be improved.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0