현재 테스트 운영중으로 불안정한 상황이 연속될 수 있습니다. 양해 부탁드립니다.
라라벨11 뒤로가기 버튼 동작 제어하기 - 브라우저 캐시 문제

라라벨11 뒤로가기 버튼 동작 제어하기 - 브라우저 캐시 문제

세션으로 제어되는 화면이 뒤로가기 만으로 여전히 드러나는 문제

라라벨 11에서 Breeze를 이용해 인증을 구현하면 아주 쉽고 빠르게 기본적인 구성을 모두 완료해줍니다. next.js에서 next-auth를 이용해 인증을 구현하는 것보다 훨씬 편리해서 감동했습니다.

하지만 아주 사소한 불만이 하나 아래와 같은 현상들이 나타납니다.

  • 로그인 후에 관리자페이지에서 바로 뒤로가기 버튼 누르면 로그인 창이 다시 뜨는 문제

  • 로그아웃 후 에 뒤로가기 버튼을 누르면 다시 관리자화면이 뜨는 문제

화면만 나타날 뿐 실제로 세션은 파괴되어 로그인을 다시 한다거나, 내용을 수정한다거나 하는 액션은 불가능합니다. 하지만 로그아웃 하고 바로 뒤로가기로 화면에 드러난다는게 썩 바람직한 상황은 아니죠. 중요한 개인정보일 경우엔 그냥 보이는 것 조차 탐탁치 않은 상황입니다.

이건 라라벨의 문제가 아니라 브라우저 캐시가 작동하는 방식때문에 생기는 현상입니다.


브라우저 캐시 문제를 미들웨어로 제어

이 부분은 미들웨어를 통해 브라우저 캐시를 삭제하는 방식으로 해결할 수 있습니다.

먼저 artisan 명령으로 DisableBrowserCache 미들웨어를 생성해줍니다.

php artisan make:middleware DisableBrowserCache;

/* app\Http\Middleware\DisableBrowserCache.php */
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class DisableBrowserCache
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        /* 기존 내용을 아래 내용으로 바꿔주세요 */
        $response = $next($request);
        /* 요청을 중간에 가로채 브라우저에 캐시를 남기지 않도록 설정하여 반환합니다. */
        $response->headers->set('Cache-Control', 'no-cache, no-store, must-revalidate');
        $response->headers->set('Pragma', 'no-cache');
        $response->headers->set('Expires', 'Fri, 01 Jan 1990 00:00:00 GMT');
        return $response;
    }
}

그리고 작성이 완료된 미들웨어를 등록해줘야합니다.

// bootstrap/app.php
<?php
...
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->alias([
            'preventBackHistory'=>DisableBrowserCache::class 
        ]);
    })
...

preventBackHistory라는 이름으로 미들웨어를 사용할 수 있습니다.

// routes/web.php
<?php
...
Route::view('dashboard', 'dashboard')
    ->middleware(['auth', 'verified', 'preventBackHistory'])
    ->name('dashboard');

Route::view('profile', 'profile')
    ->middleware(['auth','preventBackHistory'])
    ->name('profile');
...

위와 같이 필요한 부분에 preventBackHistory 라고 설정해주면, 로그인/로그아웃 때문에 세션상태에 변경이 생겼을때 뒤로 가기로 인해 여전히 기존 상태가 드러나는 현상을 막을 수 있습니다.

Blade 템플릿을 사용할때는 이 조치만으로도 충분합니다만, livewire를 사용할 경우엔 이것만으로 충분치 않을 수 있습니다.

// resourece/livewire/layout/navigation.blade.php
<?php
...
    public function logout(Logout $logout):void
    {
        $logout();
        /* navigate: true 삭제 */
        $this->redirect('/');
    }
}; ?>
...
// resources/livewire/pages/auth/login.blade.php
<?php
...
    public function login(): void
    {
        $this->validate();

        $this->form->authenticate();

        Session::regenerate();

//        $this->redirectIntended(default: route('dashboard', absolute: false), navigate: true);

        $this->redirect(route('dashboard', absolute: false));
    }
}; ?>
...

livewire를 사용할 경우엔 추가적으로 위와 같이 login과 logout에 관련된 redirect 설정을 수정해주면, 뒤로가기로 인해 발생하는 캐시 문제들을 해결해줄 수 있습니다.

hhyunki
6 days ago