(확인필요)
리다이렉트가 여러번 이루어지는 코드를 여러개의 함수로 나누게 되면,
하나의 함수에서 공통으로 사용되던 변수가 하나의 함수로 빠지면서 null이 되는 상황이 발생,
헤더에 토큰이 없다는 오류가 발생한다.
OAuth02로 로그인하기 위한 미들웨어 코드에서,
handle()메소드를 가독성을 위해 여러개의 함수로 나누는 과정에서 아래처럼 코드를 사용하였고,
아래와 같은 오류가 발생했다.
handle() 코드 안에는 여러번의 리소스 서버(네이버)와의 리다이렉트가 여러번 이루어졌다.
public function handle(Request $request, Closure $next)
{
//..
return $this->handleCallback($response2, $request);
//..
}
private function handleCallback(Response $response2, Request $request) {
//..
}
ErrorException
Attempt to read property "headers" on null
오류가 발생했고, 아래 stacktrace를 보니 헤더에 csrf토큰이 없다는 오류인 것 같았다.
local.ERROR: Attempt to read property "headers" on null {"exception":"[object] (ErrorException(code: 0): Attempt to read property \"headers\" on null at /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php:191)
[stacktrace]
#0 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(191): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError()
#1 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(80): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->addCookieToResponse()
#2 /app/vendor/laravel/framework/src/Illuminate/Support/helpers.php(263): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->Illuminate\\Foundation\\Http\\Middleware\\{closure}()
#3 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(82): tap()
#4 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167):
...
함수로 뺐다고 토큰 오류가 발생하는 건 이상해서, 통으로 옮겨야 할 구문을 부분적으로만 옮겨서 문제가 생겻나해서 의미적으로 연결된 코드들을 하나씩 handleCallback() 함수로 빼보았다.
하지만 전체 코드를 옮겼을 때도 동일한 오류가 발생하자, 함수를 나누는 코드 자체가 문제가 있다는 것을 알았다.
이후 코드를 아래처럼 고쳤고 오류는 없어졌다.
챗 GPT의 도움을 받으면,
첫번째 코드는 리다이렉트 이후 코드들이 실행되면서 $response2 변수가 null이 되어 해당 오류가 발생했고,
두번째 코드는 리다이렉트 이후 함수가 종료되어 오류가 발생하지 않는다고 한다.
즉. 아마 2번 때문인 것 같은데, 이것 때문이 맞는지 다시 확인해보긴 해야 할 듯하다.
public function handle(Request $request, Closure $next)
{
//..
//이게 아니라(x)
return $this->handleCallback($response2, $request);
//이렇게 바꾸는 게 맞다(o)
$response = $this->handleCallback($request);
// 리다이렉트 응답을 반환하고 함수 종료
if ($response instanceof \Illuminate\Http\RedirectResponse) {
return $response;
}
//..
}
private function handleCallback(Response $response2, Request $request) {
//..
}