<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Backend Tech on LOCRIAN_V Blog</title>
    <link>https://lv-blog.pages.dev/en/tags/backend-tech/</link>
    <description>Recent content in Backend Tech on LOCRIAN_V Blog</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Fri, 03 Apr 2026 11:45:26 +0800</lastBuildDate>
    <atom:link href="https://lv-blog.pages.dev/en/tags/backend-tech/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>The Fundamentals You Need to Build a Chat Room</title>
      <link>https://lv-blog.pages.dev/en/posts/programming/backend/fundamentals-for-building-a-chatroom/</link>
      <pubDate>Fri, 03 Apr 2026 11:45:26 +0800</pubDate>
      <guid>https://lv-blog.pages.dev/en/posts/programming/backend/fundamentals-for-building-a-chatroom/</guid>
      <description>&lt;h2 id=&#34;the-tcp-three-way-handshake&#34;&gt;The TCP Three-Way Handshake&lt;/h2&gt;
&lt;p&gt;Client — Server&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose of the three-way handshake&lt;/strong&gt;: the client&amp;rsquo;s send and receive are both fine, and the server&amp;rsquo;s send and receive are both fine.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&#34;first-handshake-the-client-sends-syn-synchronize-request&#34;&gt;First handshake: the client sends SYN (synchronize request)&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Client&lt;/strong&gt;: I know nothing, so I&amp;rsquo;ll send out a &lt;strong&gt;SYN&lt;/strong&gt; message and see if anyone receives it.&lt;/li&gt;
&lt;li&gt;If no one replies, I send it a few more times (timeout retransmission).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;At this moment, what the client knows is&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;I sent it, but I don&amp;rsquo;t know whether anyone received it ❌&lt;/li&gt;
&lt;li&gt;Can I receive messages? Unknown ❌&lt;/li&gt;
&lt;li&gt;Does the other side exist? Unknown ❌&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h4 id=&#34;second-handshake-the-server-replies-synack-synchronize--acknowledge&#34;&gt;Second handshake: the server replies SYN+ACK (synchronize + acknowledge)&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The &lt;strong&gt;server&lt;/strong&gt; received the client&amp;rsquo;s SYN.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why the Backend Sometimes Needs to Maintain a Refresh_Tokens Table</title>
      <link>https://lv-blog.pages.dev/en/posts/programming/backend/why-backend-maintains-a-refresh-tokens-table/</link>
      <pubDate>Mon, 02 Mar 2026 20:07:07 +0800</pubDate>
      <guid>https://lv-blog.pages.dev/en/posts/programming/backend/why-backend-maintains-a-refresh-tokens-table/</guid>
      <description>&lt;h1 id=&#34;the-normal-jwt-request-flow&#34;&gt;The Normal JWT Request Flow&lt;/h1&gt;
&lt;pre class=&#34;mermaid&#34;&gt;sequenceDiagram
    participant User as User
    participant Frontend as Frontend (browser/app)
    participant Auth as Auth server
    participant Backend as Backend API server

    Note over User,Backend: 1. Login phase
    User-&gt;&gt;Frontend: enter username/password
    Frontend-&gt;&gt;Auth: POST /login (credentials)
    Auth-&gt;&gt;Auth: verify credentials
    Auth--&gt;&gt;Frontend: return access_token + refresh_token
    Frontend-&gt;&gt;Frontend: store tokens (memory/localStorage)
    Frontend--&gt;&gt;User: login successful

    Note over User,Backend: 2. Normal request phase
    User-&gt;&gt;Frontend: request a protected resource
    Frontend-&gt;&gt;Backend: GET /api/resource&lt;br/&gt;Authorization: Bearer access_token
    Backend-&gt;&gt;Backend: verify access_token signature and expiry
    Backend--&gt;&gt;Frontend: return the requested resource
    Frontend--&gt;&gt;User: display data

    Note over User,Backend: 3. Access token expires
    User-&gt;&gt;Frontend: keep requesting
    Frontend-&gt;&gt;Backend: GET /api/resource&lt;br/&gt;Authorization: Bearer access_token (expired)
    Backend--&gt;&gt;Frontend: 401 Unauthorized (token expired)
    Frontend-&gt;&gt;Frontend: detects 401, triggers refresh logic

    Note over Frontend,Auth: 4. Token refresh phase
    Frontend-&gt;&gt;Auth: POST /refresh&lt;br/&gt;refresh_token
    Auth-&gt;&gt;Auth: verify refresh_token
    Auth--&gt;&gt;Frontend: return a new access_token (optionally a new refresh_token)
    Frontend-&gt;&gt;Frontend: update the stored access_token
    Frontend-&gt;&gt;Backend: retry the original request (new access_token)
    Backend--&gt;&gt;Frontend: return the requested resource
    Frontend--&gt;&gt;User: display data
&lt;/pre&gt;
&lt;h1 id=&#34;why-you-cant-rely-on-jwt-alone&#34;&gt;Why You Can&amp;rsquo;t Rely on JWT Alone&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;Once a refresh token is issued and the backend doesn&amp;rsquo;t store it, it becomes an &lt;strong&gt;uncontrollable long-term pass&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;You can&amp;rsquo;t forcibly log a user out&lt;/li&gt;
&lt;li&gt;You can&amp;rsquo;t log out a single device&lt;/li&gt;
&lt;li&gt;You can&amp;rsquo;t tell whether a token has been stolen (an attacker who gets the refresh token can keep refreshing the access token forever)&lt;/li&gt;
&lt;li&gt;You can&amp;rsquo;t implement session management&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&#34;the-flow-after-using-a-refresh_tokens-table&#34;&gt;The Flow After Using a refresh_tokens Table&lt;/h1&gt;
&lt;pre class=&#34;mermaid&#34;&gt;sequenceDiagram
    participant User as User
    participant Frontend as Frontend
    participant Auth as Auth server
    participant DB as Database (refresh_tokens table)
    participant Backend as Backend API server

    Note over User,DB: 1. Login phase (issue token + persist)
    User-&gt;&gt;Frontend: enter username/password
    Frontend-&gt;&gt;Auth: POST /login
    Auth-&gt;&gt;Auth: verify credentials
    Auth-&gt;&gt;DB: generate a unique refresh_token_id&lt;br/&gt;INSERT INTO refresh_tokens&lt;br/&gt;(user_id, token_hash, expires_at,&lt;br/&gt; device_info, ip_address, revoked)
    DB--&gt;&gt;Auth: insert successful
    Auth-&gt;&gt;Auth: generate access_token + refresh_token&lt;br/&gt;(refresh_token contains the id reference)
    Auth--&gt;&gt;Frontend: return access_token + refresh_token
    Frontend-&gt;&gt;Frontend: store tokens
    Frontend--&gt;&gt;User: login successful

    Note over User,Backend: 2. Normal request (same as before)
    User-&gt;&gt;Frontend: request a resource
    Frontend-&gt;&gt;Backend: GET /api/resource&lt;br/&gt;Authorization: Bearer access_token
    Backend-&gt;&gt;Backend: verify access_token
    Backend--&gt;&gt;Frontend: return the resource

    Note over Frontend,DB: 3. Access token expires → refresh
    Frontend-&gt;&gt;Backend: GET /api/resource (access_token expired)
    Backend--&gt;&gt;Frontend: 401 Unauthorized
    Frontend-&gt;&gt;Auth: POST /refresh&lt;br/&gt;refresh_token

    Note over Auth,DB: 4. Refresh verification (multi-step checks)
    Auth-&gt;&gt;Auth: parse refresh_token, extract token_id
    Auth-&gt;&gt;DB: SELECT * FROM refresh_tokens&lt;br/&gt;WHERE id = token_id
    DB--&gt;&gt;Auth: return the record
    
    Auth-&gt;&gt;Auth: verification checklist:
    Note over Auth: ✅ does token_hash match&lt;br/&gt;✅ is it expired (expires_at &gt; now())&lt;br/&gt;✅ is it revoked (revoked = false)&lt;br/&gt;✅ is the user still valid&lt;br/&gt;✅ does device info match (optional)
    
    alt all checks pass
        Auth-&gt;&gt;DB: UPDATE refresh_tokens&lt;br/&gt;SET last_used_at = now(),&lt;br/&gt;    last_used_ip = current_ip&lt;br/&gt;WHERE id = token_id
        Auth-&gt;&gt;Auth: generate a new access_token&lt;br/&gt;(optional: extend refresh_token validity)
        Auth--&gt;&gt;Frontend: return the new access_token
        Frontend-&gt;&gt;Frontend: update access_token
        Frontend-&gt;&gt;Backend: retry the original request (new token)
        Backend--&gt;&gt;Frontend: return the resource
    else checks fail
        Auth--&gt;&gt;Frontend: 401/403 (refresh failed)
        Frontend-&gt;&gt;Frontend: clear all tokens
        Frontend-&gt;&gt;User: redirect to the login page
    end

    Note over User,DB: 5. Explicit logout
    User-&gt;&gt;Frontend: click logout
    Frontend-&gt;&gt;Auth: POST /logout&lt;br/&gt;refresh_token
    Auth-&gt;&gt;DB: UPDATE refresh_tokens&lt;br/&gt;SET revoked = true&lt;br/&gt;WHERE id = token_id
    Auth--&gt;&gt;Frontend: logout successful
    Frontend-&gt;&gt;Frontend: clear local tokens
    Frontend--&gt;&gt;User: logged out

    Note over User,DB: 6. Security scenario: password change
    User-&gt;&gt;Frontend: change password
    Frontend-&gt;&gt;Auth: POST /change-password
    Auth-&gt;&gt;DB: UPDATE refresh_tokens&lt;br/&gt;SET revoked = true&lt;br/&gt;WHERE user_id = current_user_id
    Note over DB: revoke all of the user&#39;s refresh_tokens&lt;br/&gt;(force all devices to log in again)
    Auth--&gt;&gt;Frontend: password change successful
    Frontend-&gt;&gt;Frontend: clear local tokens
    Frontend--&gt;&gt;User: please log in again
&lt;/pre&gt;</description>
    </item>
  </channel>
</rss>
