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;
});
}
出于测试原因,我想使用 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;
});
}