【问题标题】:Laravel passport auth through CreateFreshApiToken always returns {"message":"Unauthenticated."}通过 CreateFreshApiToken 进行 Laravel 护照身份验证总是返回 {"message":"Unauthenticated."}
【发布时间】:2019-06-15 21:39:04
【问题描述】:

我试图让我的用户在登录后通过 JavaScript 使用我自己的 API,如 https://laravel.com/docs/5.7/passport#consuming-your-api-with-javascript 中所述。

我已经安装了 Passport。我的网络中间件定义为

'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Barryvdh\Cors\HandleCors::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \App\Http\Middleware\SetLocale::class,
        \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
    ],

我看到登录后似乎确实创建了一个“laravel_token”cookie。

然后我尝试向 API 路由发送一个简单的 get 请求

window.$.ajax({
    headers: {
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    },
    type: 'GET',
    url: 'https://mywebsite.test/api/testApi',
    success: function (response) {
        console.log(response);
    },
    error: function (xhr) {
        console.error(xhr.responseText);
    }
});

我设法得到的唯一回应是

{"message":"Unauthenticated."}

我错过了什么?

更新

请求是从子域 client.mywebsite.test 执行的,经过调查,这似乎是问题所在。从 mywebsite.test 执行 ajax 调用时,身份验证效果很好。如何解决子域的问题?

从子域请求时的请求标头:

OPTIONS /api/testApi HTTP/1.1
Host: mywebsite.test
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: https://client.mywebsite.test
Access-Control-Request-Headers: x-csrf-token,x-requested-with
Accept: */*
Referer: https://client.mywebsite.test/home

从域请求时的请求标头:

GET /api/testApi HTTP/1.1
Host: mywebsite.test
Connection: keep-alive
X-CSRF-TOKEN: fLTkaq9p62FROutzch2iE9IF864al8adFnxptbve
X-Requested-With: XMLHttpRequest
Cookie: laravel_token=[...]; XSRF-TOKEN=[...]; mywebsite_session=[...];

【问题讨论】:

  • 您的元标记 csrf-token 设置正确吗?
  • 是的。我想检查一下我的 GET 请求是否真的附加了 laravel_token,但我在 Chrome 网络开发者工具中看不到随请求发送的任何 cookie。
  • 你能用你的web 中间件堆栈编辑你的答案吗?
  • 我已经添加了 - 谢谢
  • 同样的错误!

标签: laravel laravel-passport


【解决方案1】:

这适用于我在 Laravel 5.6 项目中:

<?php

namespace App\Http\Middleware;

use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;

class EncryptCookies extends Middleware
{
    /**
     * The names of the cookies that should not be encrypted.
     *
     * @var array
     */
    protected static $serialize = true;

    /**
     * The names of the cookies that should not be encrypted.
     *
     * @var array
     */
    protected $except = [
        //
    ];
}

EncryptCookies 中间件上将属性$serialize 设置为true

来源:https://laravel.com/docs/5.6/upgrade#upgrade-5.6.30

来源:Laravel passport consuming api with js not working

【讨论】:

    【解决方案2】:

    浏览后浏览再浏览..

    事实证明,问题确实来自于未随 CORS 请求一起发送的 cookie。我通过在我的 Ajax 调用中添加“withCredentials”来修复它:

    window.$.ajax({
        headers: {
            'Accept': 'application/json',
            'X-Requested-With': 'XMLHttpRequest',
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        },
        xhrFields: {
           withCredentials: true
        },
        type: 'GET',
        url: 'https://mywebsite.test/api/testApi',
        success: function (response) {
            console.log(response);
        },
        error: function (xhr) {
            console.error(xhr.responseText);
        }
    });
    

    您还需要确保响应的标头指定接受凭据:

    header('Access-Control-Allow-Credentials: true');
    

    【讨论】:

      猜你喜欢
      • 2021-03-14
      • 2017-06-21
      • 2017-04-24
      • 1970-01-01
      • 2019-08-03
      • 2018-09-01
      • 1970-01-01
      • 2020-07-18
      • 2018-01-05
      相关资源
      最近更新 更多