我正在 Laravel 中验证 API 请求,它在本地运行良好,但是当我同时部署两者(Firebase 上的 React,不同域上的 Laravel)时,API 身份验证停止工作。这...
我正在 Laravel 中验证 API 请求,并且它在本地运行良好,但是当我同时部署两者(Firebase 上的 React,不同域上的 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 发出请求并使用不同域的 sanctum 对其进行身份验证。
///////////////// 更新 ///////////////////
我切换到 JWT 身份验证,因为 @jurandou 提到它 laravel/sanctum
不支持来自不同域的 API 授权。
在具有 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 方法的第二个参数很有用,如果感兴趣,可以 参考 sanctum doc 。
在另一个域名 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) {}
}
希望能帮助到你 ?