들어가며
ℹ️ CSR과 SSR의 개념을 명확히 이해하고 있어야 합니다.
- CSR
: 페이지가 클라이언트 측에서 로드되고, JavaScript가 실행되어 동적으로 콘텐츠를 생성합니다. 이 과정에서 사용자는 브라우저의 개발자 도구를 통해 DOM을 조작하거나 API 요청을 변경하는 등 다양한 조작을 할 수 있습니다. (useState, useEffect 등 사용 가능) - SSR
: 페이지가 서버에 렌더링되어 클라이언트에 전달되므로, 초기 로딩 시점에서 완전히 렌더링된 HTML을 받습니다. 이 경우 클라이언트에서 직접적인 조작이 제한적이며, 주로 서버와의 상호작용을 통해 업데이트됩니다.
1. OAuth 2.0 구현 실습
: 다음과 같은 순서로 진행하였습니다.
1) 각 참여자 구현
- 인가 서버: Keycloak
- 리소스 서버: Spring Resource Server, Security
- 클라이언트 애플리케이션: Next.js
2) 참여자 간 연결
- 로그인 기능
- 로그아웃 기능
- 리프레시 토큰을 통한 액세스 토큰 재발급
- 권한별 리소스 접근 제어 설정: 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기 강재연 선생님의 천재적인 두뇌 💜
반응형