lcobucci / jwt

A simple library to work with JSON Web Token and JSON Web Signature
https://lcobucci-jwt.readthedocs.io/en/stable/
BSD 3-Clause "New" or "Revised" License
7.31k stars 601 forks source link

Token validator works differently in few places #301

Closed roman-briazgalov closed 5 years ago

roman-briazgalov commented 5 years ago

Hi!

First of all, thank you very much for your lib. It's really simple to understand.

I have used JWT for REST API in my app. Then i had added WebSockets into the app and i decided to use JWT for socket connections too.

I use Laravel 5.8, PHP 7.3. JWT works well in JWTMiddleware for REST API requests.

The working scheme for sockets and JWT:

  1. The client sends JSON with JWT to server.
  2. The server validates JWT:

SocketAuthHandler.php

namespace App\Services;

use Lcobucci\JWT\Parser;
use Lcobucci\JWT\ValidationData;
use Ratchet\ConnectionInterface;

protected function validator()
    {
    $token = (new Parser)->parse($jwt);

    $data = new ValidationData();

    $data->setIssuer($host_name);
    $data->setAudience($host_name);
    $data->setSubject($user_id);

    return $token->validate($data);
}

My problem is: This function always returns TRUE. I changed JWT manually before sending to the server and this function returns TRUE anyway.

The same function is used in the JWTMiddleware, that works with REST API requests:

JWTMiddleware.php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\ValidationData;
use Lcobucci\JWT\Signer\Hmac\Sha256;

protected function validate($request, $token)
{
    $token = (new Parser())->parse((string) $token);

    $data = new ValidationData();
    $data->setIssuer($request->getHost());
    $data->setAudience($request->getHost());
    $data->setSubject($request->user()->id);

    return $token->validate($data);
}

But this one works correctly: returns TRUE with valid token and returns FALSE if the token is not valid.

I logged $host_name and $user_id that are used in these two functions, they are absolutely the same.

So could you please help me to resolve this problem? What should i check more to find the reason?

Please, let me know if i missed something in my description of the problem.

lcobucci commented 5 years ago

@roman-briazgalov glad to hear you like it! It seems like you submitted the issue without the full description (not a problem) 😁

roman-briazgalov commented 5 years ago

@roman-briazgalov glad to hear you like it! It seems like you submitted the issue without the full description (not a problem)

That's right. I pressed Ctrl+Enter accidentally. I will finish it in 10 minutes.

roman-briazgalov commented 5 years ago

@lcobucci i have changed the first message. Check it please, if you have time.

lcobucci commented 5 years ago

@roman-briazgalov could you please send us a sample token and the values you're using to validate it? It's also important to mention that you're not verifying the signature of the token, which might allow people to change the token.

roman-briazgalov commented 5 years ago

@lcobucci hI! Thanks for the fast reply!

Here is the sample of the token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjVkMTA1OTIzZjM1Njc4NGZlYzZmNWRiMiJ9.eyJpc3MiOiJwZGYubG9jIiwiYXVkIjoicGRmLmxvYyIsImp0aSI6IjVkMTA1OTIzZjM1Njc4NGZlYzZmNWRiMiIsInVzZXJfaWQiOiI1ZDEwNTkyM2YzNTY3ODRmZWM2ZjVkYjIifQ.JJPgjTJbDUXySieyEDzEMHY7XyEZrhuEFqiFvDtcxdM

And values for validating token: $host_name = pdf.loc $user_id = 5d105923f356784fec6f5db2

It's also important to mention that you're not verifying the signature of the token, which might allow people to change the token.

Oh! I didn't think about it. Thank you. I will read about it and try to add the signature verifying. I will post here about results.

roman-briazgalov commented 5 years ago

@lcobucci it's OK for now! Thanks for putting me on the right way: i have added the signature verifying to the protected function validate and validator and it works good for now!

When i create token, i use function 'getToken':

    protected function issue($request, $minutes)
    {
        $token = (new Builder())
            ->issuedBy($request->getHost())
            ->permittedFor($request->getHost())
            ->identifiedBy($request->user()->id, true)
            ->withClaim('user_id', Auth::id())
            ->getToken($this->signer, new Key(config('app.key')));

        return $token;
    }

In functions validate and validator i have added token verifying with the signature:

protected function validator()
{
    $token = (new Parser)->parse($jwt);

    $data = new ValidationData();

    $data->setIssuer($host_name);
    $data->setAudience($host_name);
    $data->setSubject($user_id);

    $signer = new Sha256();
    if (! $token->verify($signer, config('app.key'))) // this part was added for vrifying the token with signature
        return false;

    return $token->validate($data);
}

After that the validation works properly: if i change the token - validator returns false.

I'm not sure my code is absolutely right, it just shows how i made the token validation.

So the problem is resolved!

roman-briazgalov commented 5 years ago

Thanks for help, i close the issue.

lcobucci commented 5 years ago

@roman-briazgalov happy to know it helped!