在 Laravel api 调用上收到“401:未经身份验证”消息

问题描述 投票:0回答:2

不太了解 Laravel Authentication 的详细工作流程。如果有人能在这里帮助我提供一些见解,我将非常感激。

我有一个“admin”守卫,它适用于 admin.php 中的所有路由,但是,当我使用相同的中间件调用我的 api 路由时,我收到“未经身份验证”的错误。

admin.php

Route::middleware('auth:admin')->group(function () {
    Route::get('example', [ExampleController::class, 'output'])
                ->name('example');
    Route::get('verify-email', [EmailVerificationPromptController::class, '__invoke'])
                ->name('verification.notice');

    Route::get('verify-email/{id}/{hash}', [VerifyEmailController::class, '__invoke'])
                ->middleware(['signed', 'throttle:6,1'])
                ->name('verification.verify');

    Route::post('email/verification-notification', [EmailVerificationNotificationController::class, 'store'])
                ->middleware('throttle:6,1')
                ->name('verification.send');

    Route::get('confirm-password', [ConfirmablePasswordController::class, 'show'])
                ->name('password.confirm');

    Route::post('confirm-password', [ConfirmablePasswordController::class, 'store']);

    Route::post('logout', [AuthenticatedSessionController::class, 'destroy'])
                ->name('logout');

    // ログイン後TOP
    Route::get('/top', function () {
        return view('admin.top');
    })->name('top');
 });

api.php

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Admin\Image\ImageController;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});


Route::group(['middleware' => ['auth:admin']], function () {

    Route::post('/image/upload', [ImageController::class, 'upload'])->name('image.imageUpload');
});

登录请求.php

<?php

namespace App\Http\Requests\Admin\Auth;

use Illuminate\Auth\Events\Lockout;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;

class LoginRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email' => ['required', 'string', 'email'],
            'password' => ['required', 'string'],
        ];
    }

    /**
     * Attempt to authenticate the request's credentials.
     *
     * @return void
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function authenticate()
    {
        $this->ensureIsNotRateLimited();

        $this->is('admin/*') ? $guard = 'admin' : $guard = 'web';

        // if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
        if (! Auth::guard($guard)->attempt($this->only('email', 'password'), $this->boolean('remember'))) {
            RateLimiter::hit($this->throttleKey());

            throw ValidationException::withMessages([
                'email' => trans('auth.failed'),
            ]);
        }

        RateLimiter::clear($this->throttleKey());
    }

    /**
     * Ensure the login request is not rate limited.
     *
     * @return void
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function ensureIsNotRateLimited()
    {
        if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
            return;
        }

        event(new Lockout($this));

        $seconds = RateLimiter::availableIn($this->throttleKey());

        throw ValidationException::withMessages([
            'email' => trans('auth.throttle', [
                'seconds' => $seconds,
                'minutes' => ceil($seconds / 60),
            ]),
        ]);
    }

    /**
     * Get the rate limiting throttle key for the request.
     *
     * @return string
     */
    public function throttleKey()
    {
        return Str::lower($this->input('email')) . '|' . $this->ip();
    }
}

RegisteredUserController.php

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules;

class RegisteredUserController extends Controller
{
    /**
     * Display the registration view.
     *
     * @return \Illuminate\View\View
     */
    public function create()
    {
        return view('auth.register');
    }

    /**
     * Handle an incoming registration request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function store(Request $request)
    {
        $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'confirmed', Rules\Password::defaults()],
        ]);

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        event(new Registered($user));

        Auth::login($user);

        return redirect(RouteServiceProvider::HOME);
    }
}

Ajax 调用

function uploadImage($form, $i, $j) {
  busyIndicator(true);
  $form_el = $("#" + $form);
  $market_id = $("#market-id").val();
  $box_number = $("#box-number").val();
  $branch_number = $i;
  $image_number = $j;
  $image = $("#fileInput-" + $i + "-" + $j).prop("files")[0];

  $formData = new FormData();
  $formData.append("_token", $("#csrf-token")[0].value);
  $formData.append("market_id", $market_id);
  $formData.append("box_number", $box_number);
  $formData.append("branch_number", $branch_number);
  $formData.append("image_number", $image_number);
  $formData.append("image", $image, $image.name);

  $.ajaxSetup({
    headers: {
      "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
    },
  });
  $.ajax({
    type: "post",
    url: "/api/image/upload",
    enctype: "multipart/form-data",
    processData: false,
    contentType: false,
    cache: false,
    data: $formData,
    success: function (data) {
      busyIndicator(false);
      if (data["isSuccess"]) {
        $br = data["resultList"]["branchNumber"];
        $im_no = data["resultList"]["imageNumber"];
        $("#img-" + $br + "-" + $im_no).attr(
          "src",
          data["resultList"]["imagePath"]
        );
        $("#img-" + $br + "-" + $im_no).attr(
          "image-name",
          data["resultList"]["imageName"]
        );
        $("#img-" + $br + "-" + $im_no)
          .prop("onclick", null)
          .off("click");
      } else {
      }
    },
    error: function (jqXHR, status, err) {
      console.log(jqXHR);
      console.log(status);
      console.log(err);
    },
  });
}

如果我需要提供任何其他信息来帮助您理解我的问题,请随时在下面发表评论。

php laravel api
2个回答
0
投票

首先,希望您在收到此答复之前一切顺利。也许你已经解决了这个问题。然而,有一个不稳定的解释:

  1. 您需要将身份验证驱动程序设置为 sainttum,就像您已经使用
    auth:sanctum
    别名所做的那样。但我更喜欢在 config/auth.php 中构建更健壮和简洁的别名:这就是:
 'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        "api" => [
            'driver' => 'sanctum',
            'provider' => 'users' // Make sure your provider is users and it's well constructed and configured in your project
        ]
    ],

*然后你就可以使用

auth:api

  1. 然后,测试时您的本地环境域应该是127.0.0.1,否则,您的“localhost”域(在您的网络浏览器url中)将不会在域会话中存储该会话,因此该会话将不会被共享或与助手 auth() 通信,因此,
    auth:sanctum
    将不起作用。

在您的 .env 中,请检查以下内容:

SESSION_PATH=/
SESSION_DOMAIN=null
SANCTUM_STATEFUL_DOMAINS=localhost:8000,localhost:3000

否则,请将您的 fetch 或 AJAX 请求更改为

127.0.0.1:8000
,这是您执行此操作时的默认设置
php artisan serve

  1. 如果您仍然遇到错误,请告诉我。

-1
投票

假设您的应用程序正在使用 Laravel 的 API 身份验证,您必须将 api_token 发送到您的后台才能对当前用户进行身份验证。

您可以看到发送此令牌的不同示例:https://laravel.com/docs/5.8/api-authentication#passing-tokens-in-requests

© www.soinside.com 2019 - 2024. All rights reserved.