PHP-Open-Source-Saver / jwt-auth

🔐 JSON Web Token Authentication for Laravel & Lumen
MIT License
676 stars 105 forks source link

Octane + OpenSwoole: Auth::user() only works on first request #222

Open leonvd6 opened 11 months ago

leonvd6 commented 11 months ago

Subject of the issue

I've migrated my environment to Octane+Swoole and when making a request with jwt.auth middleware in api.php, the user is found using Auth::user() or $request->user(), but the subsequent request return null.

Your environment:

Q A
Bug? yes
New Feature? no
Framework Laravel
Framework version 9.52.9
Package version 2.1.0
PHP version 8.1.20

Steps to reproduce

dd(Auth::user()) in a controller API request twice in a row. Running php artisan octane:reload fixes the issue for the next request only.

Expected behaviour

Auth::user() should return the user object on every request, not just the first one.

Actual behaviour

Auth::user() returns a user on the first request, then null on any requests after that.

leonvd6 commented 11 months ago

After doing some diggin, I realised If I create my own middleware, it works. I'm not convinced its the best way forward though:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;
use PHPOpenSourceSaver\JWTAuth\Manager;
use PHPOpenSourceSaver\JWTAuth\Token;

class VerifyUserJWT
{
    /**
     * Constructor
     *
     * @param \PHPOpenSourceSaver\JWTAuth\Manager $tokenManager
     */
    public function __construct(
        private Manager $tokenManager
    ) {}

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        $tokenString = str_replace('Bearer ', '', $request->header('Authorization'));

        if (empty($tokenString)) {
            return response()->json(['message' => 'token_not_provided'], 400);
        }

        // Get user ID from from sub claim in token
        $userId = null;

        try {

            $userId = $this->tokenManager->decode(new Token($tokenString))->get('sub');

        } catch (\PHPOpenSourceSaver\JWTAuth\Exceptions\TokenExpiredException $e) {
            return response()->json(['message' => 'token_expired'], 401);
        } catch (\PHPOpenSourceSaver\JWTAuth\Exceptions\TokenInvalidException $e) {
            return response()->json(['message' => 'token_invalid'], 401);
        } catch (\PHPOpenSourceSaver\JWTAuth\Exceptions\InvalidClaimException $e) {
            return response()->json(['message' => 'invalid_claim'], 401);
        } catch (\PHPOpenSourceSaver\JWTAuth\Exceptions\JWTException $e) {
            return response()->json(['message' => 'unknown_token_error'], 401);
        }

        if (!$userId || !Auth::onceUsingId($userId)) {
            return response()->json(['message' => 'token_invalid'], 401);
        }

        return $next($request);
    }
}
Ctrl-Mota commented 4 days ago

same to me