diff --git a/CHANGELOG.md b/CHANGELOG.md
index 984e4d5c..0dc47702 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ You can find and compare releases at the GitHub release page.
 
 ### Added
 - Support for lcobucci/jwt^5.0 (and dropped support for ^4.0)
+- New `getUserId` method
 
 ## [2.3.0] 2024-05-09
 
diff --git a/src/JWTGuard.php b/src/JWTGuard.php
index a1d2d90e..534bcb7e 100644
--- a/src/JWTGuard.php
+++ b/src/JWTGuard.php
@@ -108,6 +108,26 @@ public function user()
         }
     }
 
+    /**
+     * @return int|string|null
+     */
+    public function getUserId()
+    {
+        if (null !== $this->user) {
+            return $this->user->getAuthIdentifier();
+        }
+
+        if (
+            $this->jwt->setRequest($this->request)->getToken()
+            && ($payload = $this->jwt->check(true))
+            && $this->validateSubject()
+        ) {
+            return $payload['sub'];
+        }
+
+        return null;
+    }
+
     /**
      * Get the currently authenticated user or throws an exception.
      *
diff --git a/tests/JWTGuardTest.php b/tests/JWTGuardTest.php
index 0c452a5e..cd7c99ec 100644
--- a/tests/JWTGuardTest.php
+++ b/tests/JWTGuardTest.php
@@ -172,6 +172,37 @@ public function testItShouldThrowAnExceptionIfNoTokenIsProvided()
         $this->guard->userOrFail(); // throws the exception
     }
 
+    public function testItShouldGetTheAuthenticatedUserIdIfAValidTokenIsProvided()
+    {
+        $payload = \Mockery::mock(Payload::class);
+        $payload->shouldReceive('offsetGet')->once()->with('sub')->andReturn(1);
+
+        $this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
+        $this->jwt->shouldReceive('getToken')->once()->andReturn('foo.bar.baz');
+        $this->jwt->shouldReceive('check')->once()->with(true)->andReturn($payload);
+        $this->jwt->shouldReceive('checkSubjectModel')
+            ->once()
+            ->with('\PHPOpenSourceSaver\JWTAuth\Test\Stubs\LaravelUserStub')
+            ->andReturn(true);
+
+        $this->provider->shouldReceive('getModel')
+            ->once()
+            ->andReturn('\PHPOpenSourceSaver\JWTAuth\Test\Stubs\LaravelUserStub');
+
+        $this->assertSame(1, $this->guard->getUserId());
+    }
+
+    public function testItShouldReturnNullForUserIdIfNoTokenIsProvided()
+    {
+        $this->jwt->shouldReceive('setRequest')->andReturn($this->jwt);
+        $this->jwt->shouldReceive('getToken')->andReturn(false);
+        $this->jwt->shouldReceive('check')->never();
+        $this->jwt->shouldReceive('getPayload->get')->never();
+        $this->provider->shouldReceive('retrieveById')->never();
+
+        $this->assertNull($this->guard->getUserId());
+    }
+
     public function testItShouldReturnATokenIfCredentialsAreOkAndUserIsFound()
     {
         $credentials = ['foo' => 'bar', 'baz' => 'bob'];