June 11, 2026

Note | NextAuth & OIDC Practical Example

這篇文章是 SSO Introduction 的延續,我們已經了解了 SSO 與 OIDC 的理論基礎, 現在我們將透過 NextAuth 與一個實作範例(Keycloak + Next.js + Spring Boot)來看看這些概念如何實現

實際的範例可以參考 OIDC-Example GitHub Repository 在這個 Repo 中,我實作了一個更完整的 SSO 流程,包含了前端、後端與 IdP 的整合與登出應該有的機制, 如 Token Refresh、前端與後端的安全性驗證。

1. Why NextAuth?

NextAuth.js 讓開發者不用自己手刻 OIDC 流程,只需要透過簡單的設定就能完成 SSO 登入,並且自動處理安全性驗證與 Session 管理。

在上一篇文章中,我們提到實作 OIDC 需要處理複雜的 Redirect、Token Exchange 以及各式各樣的安全性驗證(iss, aud, exp, nonce 等)。 對於前端開發者來說,如果每一項都要手刻,不僅耗時且容易產生安全漏洞。

NextAuth.js (現已更名為 Auth.js) 正是為了簡化這一切而生。它是一個為 Next.js 量身打造的驗證解決方案, 內建支持多種 OAuth/OIDC Provider (如 Google, GitHub, Keycloak),並且自動幫我們處理了:

  • 前端與 IdP 之間的導向流程
  • 回調後的 Token 交換 (Back-channel communication)
  • Session 的建立與管理 (可選 JWT 或 Database 模式)
  • 安全性標頭與 CSRF 防護

2. OIDC Practical Walkthrough: The “OIDC-Example” Project

為了讓大家更有體感,我們準備了一個包含三個組件的練習專案:

  1. Identity Provider (IdP): 使用 Keycloak (基於 Docker 運行)
  2. Frontend (RP): 使用 React + Next.js + NextAuth
  3. Resource Server (Backend): 使用 Spring Boot (Java)

2.1 NextAuth Configuration (The Frontend)

在 Next.js 中,我們透過定義 [...nextauth]/route.ts 來設定 OIDC Provider。以下是連接 Keycloak 的關鍵代碼:

import NextAuth, { NextAuthOptions } from "next-auth";
import KeycloakProvider from "next-auth/providers/keycloak";

export const authOptions: NextAuthOptions = {
  providers: [
    KeycloakProvider({
      clientId: process.env.KEYCLOAK_CLIENT_ID!,
      clientSecret: process.env.KEYCLOAK_CLIENT_SECRET!,
      issuer: "http://localhost:8081/realms/demo", // Keycloak server URL
      authorization: { params: { scope: "openid profile email" } },
    }),
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
  callbacks: {
    // Step 1: Save the Access Token from Keycloak into the encrypted JWT cookie upon successful login
    async jwt({ token, account }) {
      if (account) {
        token.accessToken = account.access_token;
      }
      return token;
    },
    // Step 2: Expose the Access Token to the frontend session so it can be used for API requests
    async session({ session, token }) {
      session.accessToken = token.accessToken as string;
      return session;
    },
  },
};

const handler = NextAuth(authOptions);
  1. providers: 透過這個 Array 來宣告你的 NextAuth 將要使用的登入方式,這裡我們使用 Keycloak、 Google 兩種方式
    • 以 Keycloak 為例應該要帶入 clientId, clientSecret, issuer,以及 authorization
  2. callbacks: 這裡可以定義登入後的回調函式,每種 callback 都有不同的用途
    • jwt callback 會在登入成功後被呼叫,我們可以在這裡把 Keycloak 回傳的 access_token 存入
    • session callback 會在前端呼叫 getSession() 時被呼叫,我們可以把 access_token 從 JWT Cookie 取出,並放入 Session 物件中

要了解一個 Callback Context 裡面有哪些屬性可以使用,最好直接去看 Source Code,官方文件只會列出部分屬性 JWTCallbackContext

NextAuth 已經內建了 Authorization Code Flow 所需要的 /api/auth/signin Endpoint, 點擊後會引導使用者至 Keycloak 登入,成功後帶回 code 並在後端換取 id_tokenaccess_token

如果你要自己寫 OIDC 的登入流程,就要自己實作各種的 Endpoint 與 Token 交換,例如 /api/auth/callback


2.2 Backend Security (The Resource Server)

當 Frontend 拿到 access_token 後,它會將其放入 HTTP Header (Authorization: Bearer <token>) 來請求後端數據。 Spring Boot 端的配置如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(Customizer.withDefaults())
            );
        return http.build();
    }
}

後端不需要自己保存使用者密碼,它只需要信任 IdP 發出的公鑰 (JWKS),驗證傳入的 JWT 是否合法即可。這就是 SSO 中「權限驗證外包」的具體展現。


3. Key Concepts Re-visited in Practice

在實作這個範例時,有幾個細節對應到了理論篇:

  1. Front-channel vs Back-channel:
    • 前端跳轉到 Keycloak 登入頁面是 Front-channel
    • NextAuth 伺服器端拿到 code 後,在後端呼叫 Keycloak /token 端點是 Back-channel
  2. Scope:
    • 在設定中我們要求了 scope: "openid profile email",這決定了 id_token 裡面會包含哪些 User Claim。
  3. JWT Verification:
    • Spring Boot 後端透過 issuer-uri 自動向 Keycloak 抓取 .well-known/openid-configuration,進而找到 jwks_uri 來驗證 Token 內容。

4. Summary

透過 NextAuth,我們可以在極短的時間內建構出符合安全標準的 SSO 登入流程。它不僅隱藏了 OIDC 的複雜實作,還提供了靈活的 Hook (如 jwtsession callbacks) 讓我們能根據需求處理 Token。

下一步,建議讀者可以嘗試在同一個 Keycloak Realm 下接入第二個不同的應用程式,體驗「在應用 A 登入後,應用 B 無須再輸入密碼」的無縫體驗。

延伸閱讀

SSO Introduction

Last Edit

06-11-2026 14:00

results matching ""

    No results matching ""

    , software, authentication, jwt, sso, nextauth