我在 Laravel 中对 API 请求进行身份验证,它在本地完美运行,但是当我部署两者时(React on Firebase,Laravel 在不同域上),API 身份验证停止工作。
这是
app/Http/Kernel.php
protected $middlewareGroups = [
'api' => [
\Fruitcake\Cors\HandleCors::class,
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
这是
config/cors.php
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['http://localhost:3000', 'https://example.web.app'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
当我使用 axios 从 React 发出请求时,收到 401 错误。
我从 ChatGPT 询问并搜索了很多,但没有成功。
我想发出请求并使用来自不同域到 Laravel 的密室对它们进行身份验证。
//////////////////更新//////////////////////////////////////////////////////////////////////////////////////////////////////
我切换到 JWT 身份验证,因为正如 @jurandou 提到的laravel/sanctum
不支持来自不同域的 API 授权。
迁移,确保存在personal_access_tokens和users表
创建一个用户,以便能够在他身上创建代币
编辑config/cors.php:
'paths' => [
'api/*',
'sanctum/csrf-cookie',
'http://www.domain-to-accept-requests/*',
],
'supports_credentials' => true
在routes/api.php中创建这些路由:(用于示例目的)
Route::get('tokens/create', [ApiController::class, 'createTokens'])->name('tokens.create');
Route::middleware('auth:sanctum')->get('/users/{user}', function (Request $request) {
$user = User::find($request->user);
return response($user);
});
使用createTokens方法创建ApiController
public function createTokens()
{
$user = User::find(1);
$token_name = 'get_api_infos_token';
$user->tokens()->where('name', $token_name)->delete();
$token = $user->createToken($token_name, ['infos:get']);
return ['token' => $token->plainTextToken];
}
如果你想检查能力,createToken 方法的第二个参数很有用,如果有兴趣,你可以参考 sainttum 文档。
在另一个域http://www.domain-to-accept-requests/,这是一个 axios js 示例
const testApi = async () => {
try {
const responseToken = await axios.get('http://www.api-domain.test/api/tokens/create')
const headers = { 'Authorization': 'Bearer ' + responseToken.data.token }
const response = await axios.get('http://www.api-domain.test/api/users/1', {headers})
console.log(response.data)
} catch (error) {}
}
希望有帮助吗?