Skip to content

Conversation

@AlexzPurewoko
Copy link
Member

@AlexzPurewoko AlexzPurewoko commented Aug 23, 2025

Dua tahun yang lalu aku sempat mengeksplorasi terkait authentication mechanism dan pencatatan session di framework yang digunakan pada Dicoding. Berikut adalah dokumentasi lengkapnya di kala itu :

https://www.notion.so/dicoding/Run-through-Auth-mechanism-in-current-Dicoding-Auth-Oauth-449ab29ee52c4ee7b669a42ac65b29e9

Intinya, setiap ada request yang masuk, entah itu melalui web browser atau API, sebuah session akan dicatat dengan flow sebagai berikut :

Request masuk -> Check ada session atau tidak, jika tidak, regenerate session ID -> Handle request -> Save session -> respond dengan cookie yang ada session-nya

Session dicatat pada di Redis. Session ID dicatat pada Cookie, sehingga ketika tidak ada cookie dengan key laravel_session yang valid, maka akan regenerate terus menerus.

Inti dari pembahasan pada dokumen diatas adalah setiap kali ada request, session selalu dicatat ke session manager, tidak melihat apakah ini berasal dari session web maupun session dari API request.

Bayangkan, satu user bisa request API ratusan - ribuan kali, dan itu akan melakukan save new session pada redis.

Problem nya

Ketika request tersebut berasal dari sesi web, itu tidak menjadi masalah karena selalu mengirimkan Cookie ketika request. Sehingga cookie tersebut persisten, tidak perlu ada regeneration ketika tiap request.

Akan tetapi, hal ini tidak berlaku pada API request. Ketika sebuah request datang dari API, utamanya dari oauth, request tersebut tidak mengandung Cookie. Di mana, menurut flow diatas, maka framework akan melakukan save new session.

Solusinya

Dimulai dari laravel 5, Guard, yang menjadi landasan untuk manajemen sesi user pada laravel memisahkan jenis guard dari user request ke Token, Cookie, dan sebagainya. Untuk case Token, ia tidak ada session disitu.

Akan tetapi, upgrading laravel 5 untuk menikmati perubahan tersebut akan susah untuk upgradenya di mana kita telah melakukan beberapa extending feature. Maka opsi upgrade adalah opsi yang overkill.

Lantas, saya ketemu ide, bagaimana kalau sesi tersebut tidak di save, atau bahkan tidak dibuat saat request API, seperti ini :

File -> Middleware.php

public function handle(Request $request, $type = HttpKernelInterface::MAIN_REQUEST, $catch = true): Response
   {
    $this->checkRequestForArraySessions($request);
    // If a session driver has been configured, we will need to start the session here
    // so that the data is ready for an application. Note that the Laravel sessions
    // do not make use of PHP "native" sessions in any way since they are crappy.
       $sessionBasedOnRequest = $request->headers->has('Authorization') ||
           ($request->isMethod('POST') && str_contains($request->getUri(), '/oauth/'));
    if ($this->sessionConfigured() && !$sessionBasedOnRequest)
    {
       $session = $this->startSession($request);
       $request->setSession($session);
    }
    $response = $this->app->handle($request, $type, $catch);
    // Again, if the session has been configured we will need to close out the session
    // so that the attributes may be persisted to some storage medium. We will also
    // add the session identifier cookie to the application response headers now.
    if ($this->sessionConfigured() && !$sessionBasedOnRequest)
    {
           $this->storeCurrentUrl($request, $session);
       $this->closeSession($session);
       $this->addCookieToResponse($response, $session);
    }
    return $respon

Sehingga ketika request dengan API, maka flownya akan seperti ini :

Request masuk -> Handle request -> respond

Potensinya, issue session ghost ini hilang dan save beberapa workaround (memory, api calls) ketika handling request.

Solusi ini sudah dicoba pada request yang datang dari Dicoding Jobs API, dan works. Akan tetapi perlu further checking pada beberapa route existing.

Setelah penerapan ini, maka kita sudah tidak bisa memanfaatkan Cookie buat request API.

Link followup :
https://teams.microsoft.com/l/message/19:996de939b1b14eb0bc317ab2a6464ce7@thread.tacv2/1756000586635?tenantId=a266a087-622d-47cc-8c26-c15071fe3650&groupId=c9e1dd91-06b9-4afb-8082-f9874705b076&parentMessageId=1756000586635&teamName=Engineering&channelName=Hacking&createdTime=1756000586635

@AlexzPurewoko AlexzPurewoko self-assigned this Aug 23, 2025
@AlexzPurewoko AlexzPurewoko changed the title [Improvements] Prevent session creation when the request is coming from REST API/Oauth access token [Improvements] Prevent session creation when the request is coming from Token based Auth Aug 29, 2025
return $response;
}

private function isRequestFromWebBasedAuth(Request $request): bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ini metodenya sebenarnya kurang pas. Karena kondisi !$isFromTokenBasedAuthentication tidak hanya berasal dari web auth. Usulku lebih baik dibuat eksplisit saja isTokenBasedRequest().

@rizqyhi
Copy link
Member

rizqyhi commented Sep 8, 2025

After discussion with @AlexzPurewoko, this improvement will be moved to app, instead of framework. This is because the implementation would be app-specific and bounded by the business requirement of the app.

@rizqyhi rizqyhi closed this Sep 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants