Laravel Http 客户端 419 未知状态

Laravel Http Client 419 unknown status

出于测试原因,我想使用 Laravel HTTP 客户端发出以下 Post 请求:

$test =  Http::post(route('users.leads.store', ['user' => $user->id]), [
            "company_name" => "TESTCOMPANY",
            "zip" => "49685",
            "city" => "BÜHREN",
            "street" => "MÜHLENKAMP 3",
            "contact_name" => "FABIANLUKASSEN",
            "phone1" => "017691443785",
            "email" => "FABIANLUKASSEN@TESTEN.DE",
            "website" => "www.fabianlukassen.de",
            "category" => "Hotel",
            "closed_until" => now(),
            "appointment_end" => now()->addDays(1),
            "appointment_comment" => "HALLO ICH BIN FABIAN",
            "additional_contacts" =>  "",
            "phone2" => "",
            "sub_category" => "",
            "expert_status" => 0
        ]);

我知道路线运行良好。但是,通过在 phpStorm 中进行调试,我可以看到 $test 变量包含 419 错误(未知状态)。有人知道怎么回事吗?

(我正在使用 laravel 8)

通常在 Laravel 中,419 页面过期错误来自 CSRF 中间件,这意味着验证 CSRF 令牌时失败。将您的 CSRF 令牌添加到您的测试请求或考虑在测试时禁用 CSRF 中间件。

我同意@ElektaKode 的观点,这个问题可能是由于缺少 csrf 令牌造成的。

为了在测试时禁用 CSRF 中间件, 通过更新:

/app/Http/Midddleware/VerifyCsrfToken.php 关闭此路由的 CSRF 令牌
protected $except = [ 'your-route-url' ];

然后可以使用api认证跟进

使用api认证最简单的方法,按照这个doc, 其他方法是将 Laravel passport or using jwt 用于 api。(这两种方法都将花费更多时间来设置,因为您使用 api 身份验证进行测试是您的首选方法。)

Post 使用 Laravels HTTP 客户端请求

 $test = Http::post(route('users.leads.store', ['user' => $user->id]), [
            "company_name" => "TESTCOMPANY",
             "place_id" => null,
             "street" => "MÜHLENKAMP 3",
            "zip" => "49685",
            "city" => "BÜHREN",
             "title" => null,
            "contact_name" => "FABIANLUKASSEN",
             "additional_contacts" =>  null,
            "phone1" => "+49 163 3006603",
             "phone2" => null,
            "email" => "FABIANLUKASSEN@TESTEN.DE",
             "category" => "Hotel",
             "sub_category" => null,
            "website" => "www.fabianlukassen.de",
             "status" => 1,
             "expert_status" => 0,
             "coordinates" => null,
             "expert_id" => 1,
             "agent_id" => null,
             "blocked" => 0,
             "important_note" => null,

        ]);

路线

Route::apiResource('users.leads', UserLeadController::class);

UserLeadController 中的存储方法

 public function store(User $user, CreateLeadRequest $request)
{
    //TODO: Relocate validation to request class
    if(!UserLeadController::isPhone("test", $request->phone1)) {
        abort(400, "Keine gültige Telefonnummer!");
        return;
    }

    if(!UserLeadController::isPhoneNumberUnique("test", $request->phone1)) {
        abort(400, "Die Telefonnummer existiert bereits!");
        return;
    }
    /**
     * The logged in User
     * @var User $agent
     */
    $agent = Auth::user();
    $phoneUtil = PhoneNumberUtil::getInstance();

    $lead = new Lead();
    $lead->fill($request->except(['appointment_end', 'appointment_comment']));
    // Leads created by experts will be blocked
    if ($user->id === $agent->id) {
        $lead->blocked = true;
    }
    $numberProto = $phoneUtil->parse($lead->phone1, 'DE');
    $lead->phone1 = $phoneUtil->format($numberProto, PhoneNumberFormat::INTERNATIONAL);
    try {
        $lead->save();
    } catch (QueryException $e) {
        //$message = 'Lead besteht bereits.';
        //return Response::json(['errors' => $message], 422);
        abort(422, "Lead besteht bereits!");
        return;
    }
    if ($request->closed_until) {
        $lead->closed_until = Carbon::create($request->closed_until);
        $event_end = $request->appointment_end
            ? Carbon::parse($request->appointment_end)
            : Carbon::parse($request->closed_until)->addMinutes(90);
        $lead->calendarEvents()->save(new CalendarEvent([
            'body'        => $request->appointment_comment ?? "Wurde von {$this->roleDescriptor($agent->roles)}" . $agent->name . " angelegt.",
            'type'        => CalendarEventType::CALLCENTER_APPOINTMENT,
            'event_begin' => $lead->closed_until,
            'event_end'   => $event_end,
        ]));
        $lead->status = LeadState::APPOINTMENT;
        $lead->expert_status = LeadExpertAcceptance::ACCEPTED;
    } else {
        $lead->status = LeadState::OPEN;
    }

    if (isset($request->agent)) {
        $lead->agent_id = $request->agent;
    }
    try {
        $user->leads()->save($lead);
        $lead->comments()->save(new Comment([
            'body'             => "Wurde von {$this->roleDescriptor($agent->roles)}" . $agent->name . " angelegt.",
            'user_id'          => $agent->id,
            'commentable_type' => 'lead',
            'commentable_id'   => $lead->id,
            'reason'           => 'CREATED',
            'date'             => now('Europe/Berlin'),
        ]));
        if ($request->closed_until) {
            $lead->comments()->save(new Comment([
                'body'             => "Termin wurde von {$this->roleDescriptor($agent->roles)}" . $agent->name . " vereinbart.",
                'user_id'          => $agent->id,
                'commentable_type' => 'lead',
                'commentable_id'   => $lead->id,
                'reason'           => 'APPOINTMENT',
                'date'             => now('Europe/Berlin')->addMinute(),
            ]));
        }
    } catch (QueryException $e) {
        //not sure if this works
        $message = $e->getMessage();
        abort(400, $message);
        return;
    }

    if (empty($message)) {
        return Response::json(['message' => 'Lead saved', 'lead' => new LeadSingleResource($lead)]);
    } else {
        return Response::json(compact('message'), 500);
    }
}

//TODO: relocate function to rule object
protected static function isPhoneNumberUnique($attribute, $value) {
    $withSpace = PhoneFormatter::formatInternational($value);
    $withoutSpace = preg_replace('/ /', '', $withSpace);
    $protos = [$withSpace, $withoutSpace]; // Necessary because legacy (25.06.2020).
    $booleanTest = Company::query()->whereIn('phone', $protos)->doesntExist()
        || Lead::query()->whereIn('phone1', $protos)->orWhereIn('phone2', $protos)->doesntExist();
    return $booleanTest;
}

//TODO: relocate function to rule object
protected static function isPhone($attribute, $value) {
    if (!$value) {
        return false;
    }
    $phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
    $test = $phoneUtil->isValidNumber($phoneUtil->parse($value, 'DE'));
    return $test;
}

潜在客户模型中的可填充变量

protected $fillable = [
    'company_name',
    'place_id',
    'street',
    'zip',
    'city',
    'title',
    'contact_name',
    'additional_contacts',
    'phone1',
    'phone2',
    'email',
    'category',
    'sub_category',
    'website',
    'status',
    'expert_status',
    'coordinates',
    'expert_id',
    'agent_id',
    'blocked',
    'important_note'
];

如前所述,我收到 200 OK 状态。此外,在 Vue.js 组件中,我完成了以下 axios post 请求,它也工作正常。

 axios
        .post(`/api/users/${this.user_id}/leads`, {
          "company_name": this.companyName,
          "zip": this.zipCode,
          "city": this.city,
          "street": this.streetAndHouseNumber,
          "contact_name": this.contactPartner,
          "phone1": this.contactPartnerPhoneNumber,
          "email": this.contactPartnerEmail,
          "website": this.website,
          "category": this.category,
          "closed_until": this.appointmentStart,
          "appointment_end": this.appointmentEnd,
          "appointment_comment": this.comment,

          //not used but needed (don't know the purpose)
          "additional_contacts": "",
          "phone2": "",
          "sub_category": "",
          "expert_status":this.expert_status,


        }).then(() => {
          window.location.href = this.routeSuccess;
        }).catch((error) => {
          this.showErrorAlert = true;
          this.errorAlertMessage = error.response.data.message;
        });
  }