본문 바로가기

JavaScript/OAuth

OAuth 2.0 구현 실습 - 로그아웃 기능 프로세스 (CSR, SSR, Next.js, Keycloak)

들어가며

ℹ️ CSR과 SSR의 개념을 명확히 이해하고 있어야 합니다.
  • CSR
    : 페이지가 클라이언트 측에서 로드되고, JavaScript가 실행되어 동적으로 콘텐츠를 생성합니다. 이 과정에서 사용자는 브라우저의 개발자 도구를 통해 DOM을 조작하거나 API 요청을 변경하는 등 다양한 조작을 할 수 있습니다. (useState, useEffect 등 사용 가능)
  • SSR
    : 페이지가 서버에 렌더링되어 클라이언트에 전달되므로, 초기 로딩 시점에서 완전히 렌더링된 HTML을 받습니다. 이 경우 클라이언트에서 직접적인 조작이 제한적이며, 주로 서버와의 상호작용을 통해 업데이트됩니다.

 


 

1. OAuth 2.0 구현 실습

: 다음과 같은 순서로 진행하였습니다.

1) 각 참여자 구현

  1. 인가 서버: Keycloak
  2. 리소스 서버: Spring Resource Server, Security
  3. 클라이언트 애플리케이션: Next.js

2) 참여자 간 연결

  1. 로그인 기능
  2. 로그아웃 기능
  3. 리프레시 토큰을 통한 액세스 토큰 재발급
  4. 권한별 리소스 접근 제어 설정: Keycloak에서 scope 기반 매핑

 


2. 로그아웃 기능 프로세스

✅ CSR에서 SSR로 넘겨서 로그아웃 기능을 구현하는 이유는 다음과 같습니다.
: Keycloak에서 로그아웃을 하기 위해선 URL, ID, TOKEN 등의 값이 필요한데(Keycloak의 문법), 이를 CSR에서 구현하면 값들이 전부 노출됩니다.
보안을 위해 SSR에서 처리하기 위해 api\auth\logout\route.js - SSR에서 처리합니다.(Next.js의 문법)
AuthStatus api\auth\logout\route.js .env.local
CSR   SSR   SSR
keyclockSessionLogout   GET   Keycloak 엔드포인트
// AuthStatus.js
"use client";
...
          onClick={() =>
            keycloakSessionLogout().then(() => signOut({ callbackUrl: "/" }))
          } // callbackUrl: 로그아웃 처리 후 이동할 URL 경로
...
async function keycloakSessionLogout() {
  try {
    // api/auth/logout/route.js의 GET() 호출한다.
    await fetch("/api/auth/logout", { method: "GET" });
  } catch (error) {
    console.error(error);
  }
  
  
  
  
// api/auth/logout/route.js
export async function GET() {
...
      const response = await fetch(KEYCLOAK_URL, { method: "GET" });
...
    // keycloak의 엔드포인트로 호출한다.
    const KEYCLOAK_URL = `${
      process.env.END_SESSION_URL
    }?id_token_hint=${idToken}&post_logout_redirect_uri=${encodeURIComponent(
      process.env.NEXTAUTH_URL
    )}`; // 로그아웃 처리 후 리다이렉트할 경로




// .env.local
AUTH_SECRET="q9+xX+JodcossRbL0y3idIoptcZe3k2P3jB1Li316tw=" # Added by `npx auth`. Read more: https://cli.authjs.dev

# Keycloak에 클라이언트 애플리케이션(next.js)을 제공되는 값
AUTH_KEYCLOAK_ID=demo-frontend
AUTH_KEYCLOAK_SECRET=DyfOmWldMkNOeT50Yxd3ECQFlX55opfp

# (액세스, 리프레시, ID) 토큰 발행자 URL
AUTH_KEYCLOAK_ISSUER=http://localhost:8080/realms/my-first-demo

# Keyclock 인가 서버에서도 로그인한 사용자 세션에 대한 로그아웃 처리를 수행할 URL
# "end_session_endpoint": "http://localhost:8080/realms/my-first-demo/protocol/openid-connect/logout"
NEXTAUTH_URL=http://localhost:3000
END_SESSION_URL=http://localhost:8080/realms/my-first-demo/protocol/openid-connect/logout

 


  • 참고 자료
    : 우리에프아이에스 아카데미 3기 강재연 선생님의 천재적인 두뇌 💜
반응형