【问题标题】:Laravel Http Client 419 unknown statusLaravel Http 客户端 419 未知状态
【发布时间】:2020-11-23 15:03:21
【问题描述】:

出于测试原因,我想使用 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 post httpclient


【解决方案1】:

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

为了在测试时禁用 CSRF 中间件, 通过更新在/app/Http/Midddleware/VerifyCsrfToken.php 关闭此路由的 CSRF 令牌:

protected $except = [ 'your-route-url' ];

那你就可以使用api认证来跟进了。

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

【讨论】:

  • 谢谢,这有效,我现在得到 200 OK 状态。但是,post 请求没有创建数据库条目。有什么建议吗?
  • 显示您想要在哪里进行数据库输入的代码,您如何收到响应,您在$response->json() 中得到了什么,也请接受答案,让我有动力在 stackoverflow 上帮助其他人
【解决方案2】:

通常在 Laravel 中,419 Page Expired 错误来自 CSRF 中间件,这意味着验证 CSRF 令牌时出现故障。将您的 CSRF 令牌添加到您的测试请求中,或考虑在测试时禁用 CSRF 中间件。

【讨论】:

    【解决方案3】:

    使用 Laravel 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中的Store方法

     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 发布请求,它也可以正常工作。

     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;
            });
      }
    

    【讨论】:

    • 您可以做的一件事是使用返回来调试存储中的代码,例如首先检查是否在存储方法中收到 $request,方法是在第一行的响应中返回 $return,您将知道错误在哪里谎言,这也是一个答案块,您不能在此处添加要询问的代码,我建议您编辑问题,因为您是新用户,您的答案已被审核,因此可能有机会将其删除跨度>
    猜你喜欢
    • 2019-07-16
    • 2018-05-26
    • 2019-10-22
    • 2021-06-21
    • 2018-07-18
    • 2018-09-20
    • 2018-08-24
    • 2021-08-28
    • 2021-06-11
    相关资源
    最近更新 更多