Laravel Sanctum + Nuxt3未经认证

wi3ka0sx  于 2023-11-20  发布在  其他
关注(0)|答案(2)|浏览(139)

我相信,我完全失去了阅读n文章和文档,不知道什么是正确的方式使用Sanctum。只是一个抬头,我试图达到/创建之前谈论更多的问题。我想建立一个应用程序,将只通过API通信,基本上是通过令牌。为此,我的后端将使用Laravel创建,前端使用Nuxt 3。我认为我的Laravel设置大部分是正确的,但整个工作流程是不正确的,现在的问题是,从Nuxt应用程序登录后,我成功地接收到用户数据和令牌。然而,当我试图使用auth:sanctum进入受保护的端点时-我收到401(未经授权).然而,如果我手动附加承载令牌请求-一切都很好,这是有道理的,但是!我读到的地方,如果我在请求中使用withCredentials:true,它将手动将令牌附加到头部作为授权承载。另外,我的脑海中出现了一个问题-如果将令牌保存在localStorage中真的很糟糕吗?
这里是Laravel部分,它从登录返回令牌:

$token = Auth::user()->createToken('basic-app-token')->plainTextToken;

 $cookie = cookie('auth_token', $token, 30, null, null, false, true, false, 'Strict');

 return $this->successfullRequest($response, $message,200)->withCookie($cookie);

字符串
也许附加我自己的cookie没有意义?Laravel从/sanctum/csrf-cookie将识别用户并授权它?
用户成功登录并接收令牌:

await axios.get('http://localhost:5000/sanctum/csrf-cookie', {
        withCredentials: true
    });

    const {data: {data: {user, token}}} = await axios.post('http://localhost:5000/api/v1/auth/login', userData, {
        headers: {
            'Content-Type': 'application/json'
        },
        withCredentials: true,
    });


下一个对protected route的请求看起来像这样:

const request = await axios.get('http://localhost:5000/api/v1/company', {
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        },
        withCredentials: true
    });

    console.log(request); // Returns 401

uxhixvfz

uxhixvfz1#

在后端,您应该在数据库中找到用户并为他们创建令牌,然后将其返回到前端。

public function signIn(Request $request): JsonResponse
{
    $request->validate([
        'email' => 'required|email',
        'password' => 'required|string'
    ]);

    $user = User::query()->where('email', $request->get('email'))->first();

    if (!$user || !Hash::check($request->get('password'), $user->password)) {
        throw new AuthorizationException(
            'The provided credentials are incorrect.',
            401
        );
    }

    return response()->json(['token' => $user->createToken(config('app.name'))->plainTextToken]);
}

字符串
在前端,您应该将令牌存储在localStorage或Cookie中(这是优先级),但为了简单起见,您可以将其放在localStorage中。然后将Bearer + token添加到每个axios请求中。

const base = axios.create({
    baseURL: process.env.VUE_APP_URL,
    headers: {
        Authorization: `Bearer ${localStorage.getItem('user-token') || ''}`
    },
    responseType: 'json', // default
    responseEncoding: 'utf8', // default
});
base.defaults.withCredentials = true;

 api.post('/auth/login', {email: this.email, password: this.password})
    .then(response => response.data)
    .then(response => {
       localStorage.setItem('user-token', response.token);
    })

 api.get('/api/v1/company').then(response => console.log(response.data));

  • 如果你想使用Cookie,那么你需要withCredentials,在localStorage的情况下,你不需要考虑它。*
  • Sanctum Guard* 将获取令牌本身并检查它是否存在于数据库中。您可以在vendor/laravel/sanctum/src/Guard.php中看到这一点
public function __invoke(Request $request)

....

if ($token = $request->bearerToken()) {
    $model = Sanctum::$personalAccessTokenModel;

    $accessToken = $model::findToken($token);

    if (! $this->isValidAccessToken($accessToken) ||
        ! $this->supportsTokens($accessToken->tokenable)) {
        return;
    }

    if (method_exists($accessToken->getConnection(), 'hasModifiedRecords') &&
        method_exists($accessToken->getConnection(), 'setRecordModificationState')) {
        tap($accessToken->getConnection()->hasModifiedRecords(), function ($hasModifiedRecords) use ($accessToken) {
            $accessToken->forceFill(['last_used_at' => now()])->save();

            $accessToken->getConnection()->setRecordModificationState($hasModifiedRecords);
        });
    } else {
        $accessToken->forceFill(['last_used_at' => now()])->save();
    }

    return $accessToken->tokenable->withAccessToken(
        $accessToken
    );
}

t1qtbnec

t1qtbnec2#

刚刚注意到..我以为我有正确的.env文件SANCTUM_STATEFUL_DOMAINS.它是SANCTUM_STATEFUL_DOMAINS=localhost,必须有我的SPA的端口,对于当前情况:SANCTUM_STATEFUL_DOMAINS=localhost:3000

相关问题