我在使用 json 登錄的 symfony 6 上有一個非常奇怪的行為。Json 登錄的配置與他們的示例一樣。
我添加了最簡單的 Cors 處理
class CorsSubscriber implements EventSubscriberInterface
{
public function onKernelResponse(ResponseEvent $event)
{
$response = $event->getResponse();
$response->headers->add([
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Headers' => 'Content-Type'
]);
}
public static function getSubscribedEvents()
{
return [
KernelEvents::RESPONSE => 'onKernelResponse',
];
}
}
登錄控制器
class LoginController extends AbstractController
{
#[Route('/login', name: 'api_login')]
public function login(#[CurrentUser] ?User $user): JsonResponse
{
if ($user === null) {
$this->json([
'message' => 'Not found',
], JsonResponse::HTTP_UNAUTHORIZED);
}
$token = "token"; // some token logik follows
$response = new JsonResponse([
'user' => $user->getUserIdentifier(),
'token' => $token,
]);
return $response;
}
}
同樣,基本上直接從他們的教程中取出。
還設定了資料庫并預先添加了一個用戶。如果我現在想通過 Rest App 登錄(我使用 Insomnia),一切都會按預期作業。我得到了用戶識別符號(電子郵件)和令牌。
但是,當我想通過 Angular Web 應用程式執行完全相同的操作時,我會在日志中收到以下訊息:[critical] Uncaught Error: Call to a member function getUserIdentifier() on null
let data = {username: "[email protected]", password: "test123"};
this.http
.post('http://localhost:8000/login', data)
.subscribe({
next: (value) => {
console.log(value);
},
});
有趣的事情,因為我檢查 $user 是否為空......但最有趣的是,如果我將$user->getUserIdentifier()呼叫更改為“ $user” - 它可以作業并且我會回傳整個用戶物件(我在 中定義的所有內容json_serializable)
同樣,getUserIdentifier 來自 symfony 本身
/**
* A visual identifier that represents this user.
*
* @see UserInterface
*/
public function getUserIdentifier(): string
{
return (string) $this->email;
}
我錯過了什么?
uj5u.com熱心網友回復:
在檔案check_path: api_login中定義在“security.yaml”中。
在 ApiLoginController#[route('/api/login', name:'api_login')]
我想將其更改為路徑“ /login”。
因此我check_path: login在 security.yaml 中定義
并在控制器中#[route('/login', name:'api_login')]
但是,名稱也必須是“login”,例如#[route('/login', name:'login')]
uj5u.com熱心網友回復:
發現出了什么問題。
- 沒有回報
if ($user === null) {
$this->json([
'message' => 'Not found',
], JsonResponse::HTTP_UNAUTHORIZED);
}
我錯過了return之前$this->json,允許通話繼續進行,即使$user確實如此null。
- 預檢 Cors
老實說,我對 cors 沒有太多的經驗和知識,也沒有真正意識到正在進行的飛行前呼叫。但這就是問題所在。
public function onKernelRequest(RequestEvent $event)
{
if (!$event->isMainRequest()) {
return;
}
$request = $event->getRequest();
$method = $request->getRealMethod();
if ('OPTIONS' == $method) {
$response = new Response();
$event->setResponse($response);
}
}
public static function getSubscribedEvents()
{
return [
KernelEvents::RESPONSE => ['onKernelResponse', 9999],
KernelEvents::REQUEST => ['onKernelRequest', 9999]
];
}
我擴展了 CorsSubscriber 以檢查 MethodOPTION是否不是主要請求,并且僅發送 200 以通過預檢。這幫助我理解了它背后的邏輯:
- https://gist.github.com/rordi/42de5982e877e1177a0e6a98ee8415ea
- https://www.upbeatproductions.com/blog/cors-pre-flight-requests-and-headers-symfony-httpkernel-component
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/435249.html
下一篇:回圈到回圈的變數傳輸,或資料錯誤
