axios Laravel Sanctum用于不同域的API认证

zbdgwd5y  于 2023-05-12  发布在  iOS
关注(0)|答案(1)|浏览(108)

我在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 auth,因为@jurandou提到laravel/sanctum不支持来自不同域的API授权。

bq3bfh9z

bq3bfh9z1#

在具有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文档。
在另一个域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) {}
    }

希望有帮助?

相关问题