'test-fastapi-agent-secret-0123456789ABCDEF']); config(['services.fastapi_agent.jwt_algorithm' => 'HS256']); Route::middleware(['api.auth']) ->get('/__test/sanctum-or-fastapi-jwt', fn (Request $request) => response()->json([ 'openid' => $request->attributes->get('fastapi_openid'), 'user_id' => $request->user()?->id, ])); }); function fastApiJwt(array $overrides = []): string { $payload = array_merge([ 'sub' => 'mini-app-openid-123', 'iat' => time(), 'exp' => time() + 3600, ], $overrides); return JWT::encode($payload, 'test-fastapi-agent-secret-0123456789ABCDEF', 'HS256'); } test('a valid Sanctum token authenticates as a real user, no openid attribute set', function () { $user = User::factory()->create(); $token = $user->createToken('test-token')->plainTextToken; $this->withHeader('Authorization', "Bearer {$token}") ->getJson('/__test/sanctum-or-fastapi-jwt') ->assertSuccessful() ->assertJson(['openid' => null, 'user_id' => $user->id]); }); test('a valid FastAPI JWT authenticates with the verified openid claim and no user', function () { $token = fastApiJwt(['sub' => 'agent-openid-456']); $this->withHeader('Authorization', "Bearer {$token}") ->getJson('/__test/sanctum-or-fastapi-jwt') ->assertSuccessful() ->assertJson(['openid' => 'agent-openid-456', 'user_id' => null]); }); test('an expired FastAPI JWT is rejected', function () { $token = fastApiJwt(['exp' => time() - 60]); $this->withHeader('Authorization', "Bearer {$token}") ->getJson('/__test/sanctum-or-fastapi-jwt') ->assertUnauthorized(); }); test('a FastAPI JWT signed with the wrong secret is rejected', function () { $token = JWT::encode(['sub' => 'agent-openid-456', 'exp' => time() + 3600], 'wrong-secret-0123456789ABCDEFGHIJKLMNOP', 'HS256'); $this->withHeader('Authorization', "Bearer {$token}") ->getJson('/__test/sanctum-or-fastapi-jwt') ->assertUnauthorized(); }); test('a malformed bearer token is rejected', function () { $this->withHeader('Authorization', 'Bearer not-a-real-token') ->getJson('/__test/sanctum-or-fastapi-jwt') ->assertUnauthorized(); }); test('a request with no Authorization header is rejected', function () { $this->getJson('/__test/sanctum-or-fastapi-jwt')->assertUnauthorized(); });