You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Passport客户端user_id为null致401验证失败求助

Troubleshooting Laravel Passport 401 Errors with React

Let’s walk through fixing your 401 issue — first, let’s clear up a common misconception about the oauth_clients.user_id field, then dig into the actual causes of unauthorized requests.

First: Why oauth_clients.user_id is Null (and That’s Okay)

When you run php artisan passport:install, the two clients it creates are global application clients, not user-specific:

  • One is a password_client (for the password grant flow you’re likely using)
  • The other is a personal_access_client (for personal access tokens)

These clients are meant to be used by your React app itself, so their user_id being null is expected. The user association happens in the oauth_access_tokens table when a token is generated, not on the client itself. So this isn’t the root cause of your 401 error.

Common Fixes for 401 Unauthorized Requests

1. Verify Your Request Headers

Your React app must send the access token in the Authorization header using the Bearer scheme. Double-check your API call code:

// Example with Axios
import axios from 'axios';

const fetchData = async (token) => {
  try {
    const response = await axios.get('/api/your-endpoint', {
      headers: {
        'Authorization': `Bearer ${token}`, // Critical: Don’t forget the "Bearer " prefix
        'Accept': 'application/json'
      }
    });
    return response.data;
  } catch (error) {
    console.error('Request failed:', error.response);
  }
};

If using fetch, the syntax is similar:

fetch('/api/your-endpoint', {
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  }
});

2. Ensure Routes Use the auth:api Middleware

In your Laravel routes/api.php, confirm that protected routes are using the auth:api middleware:

// Correct: Protected route
Route::get('/user/data', [UserController::class, 'getData'])
    ->middleware('auth:api');

// Incorrect: No middleware (or using web middleware)
Route::get('/user/data', [UserController::class, 'getData']);

3. Check Your config/auth.php Configuration

Make sure the api guard is set to use the passport driver:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport', // Must be "passport", not "token" or other drivers
        'provider' => 'users',
    ],
],

4. Validate Token Generation Parameters

When generating a token via the password grant, ensure you’re using the correct client credentials (from the password_client entry in oauth_clients):

// Example backend token generation (or from your React app’s POST request)
$http = new \GuzzleHttp\Client();

$response = $http->post(config('app.url') . '/oauth/token', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => env('PASSPORT_PASSWORD_CLIENT_ID'), // Use the password client’s ID
        'client_secret' => env('PASSPORT_PASSWORD_CLIENT_SECRET'), // Its secret
        'username' => $request->email,
        'password' => $request->password,
        'scope' => '', // Leave empty unless using scopes
    ],
]);

return json_decode((string) $response->getBody(), true);

Store the client ID and secret in your .env file instead of hardcoding them.

5. Check CORS Settings

Since you’re using React (a separate frontend), ensure Laravel allows cross-origin requests to include the Authorization header. If using barryvdh/laravel-cors, update config/cors.php:

return [
    'paths' => ['api/*', 'oauth/*'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['http://your-react-app-url.com'], // Restrict to your frontend domain in production
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'], // Or explicitly list 'Authorization'
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true,
];

Then apply the cors middleware to your API routes.

6. Verify Token Expiry and Revocation

Check the oauth_access_tokens table to confirm your token isn’t expired (expires_at column) or revoked (revoked column). You can extend token validity in your AuthServiceProvider:

use Laravel\Passport\Passport;

public function boot()
{
    $this->registerPolicies();
    Passport::routes();

    // Extend token validity (example: 7 days)
    Passport::tokensExpireIn(now()->addDays(7));
}

Next Steps

If none of these fix the 401, share:

  • The exact API request you’re making (including full headers)
  • The full response body from the 401 error
  • Your Laravel version and Passport version

内容的提问来源于stack exchange,提问作者Richard Jensen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:19:36