Next.js 15 + Spring Boot 3.3 연동 방법
Next.js 15(App Router)과 Spring Boot 3.3을 연동할 때, 인증(Authentication) 및 API 통신을 고려해야 합니다. 일반적으로 NextAuth.js와 Axios Instance를 활용하는 방식이 많이 사용됩니다.
1. Next.js 15 프로젝트 생성
아래 명령어로 Next.js 15 프로젝트를 생성합니다:
npx create-next-app@latest frontend
설정 옵션 예시:
- TypeScript: Yes
- ESLint: Yes
- Tailwind CSS: Yes
- src 디렉토리 사용: Yes
- App Router 사용: Yes
- Turbopack 사용: Yes
- Import alias 설정: @/*
추가 패키지 설치
npm install next-auth axios @tanstack/react-query tailwind-merge tailwindcss-animate zod dotenv
2. 인증(Authentication) - NextAuth.js 사용
NextAuth.js를 사용하면 Spring Boot의 JWT 또는 세션 기반 인증을 쉽게 연동할 수 있습니다.
✅ Spring Boot와 NextAuth 연동 방식
- Spring Boot에서 JWT 또는 세션 기반 로그인 API 제공 (/api/auth/login)
- NextAuth에서 authorize 함수 내에서 로그인 API 호출
- 로그인 성공 시 JWT를 세션에 저장 후 클라이언트가 사용
NextAuth 설정 (auth.ts)
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
export const authOptions = {
providers: [
CredentialsProvider({
name: "Credentials",
credentials: {
username: { label: "Username", type: "text" },
password: { label: "Password", type: "password" },
},
async authorize(credentials) {
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(credentials),
});
const user = await res.json();
if (!res.ok) throw new Error(user.message);
return user; // JWT or session info
},
}),
],
callbacks: {
async jwt({ token, user }) {
if (user) token.accessToken = user.accessToken;
return token;
},
async session({ session, token }) {
session.accessToken = token.accessToken;
return session;
},
},
secret: process.env.NEXTAUTH_SECRET,
};
export default NextAuth(authOptions);
3. API 요청 - Axios Instance + React Query 활용
Next.js 클라이언트 및 서버에서 Spring Boot API를 호출할 때 Axios Instance를 사용하면 편리하게 인증 정보를 관리할 수 있습니다.
Axios Instance 설정
import axios from "axios";
import { getSession } from "next-auth/react";
const apiClient = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
headers: {
"Content-Type": "application/json",
},
});
// 요청 인터셉터: JWT 자동 추가
apiClient.interceptors.request.use(async (config) => {
const session = await getSession();
if (session?.accessToken) {
config.headers.Authorization = `Bearer ${session.accessToken}`;
}
return config;
});
export default apiClient;
4. Middleware를 활용한 인증 처리
Next.js의 Middleware를 활용하여 인증이 필요한 페이지에 접근을 제한할 수 있습니다.
middleware.ts 예제
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { getToken } from "next-auth/jwt";
export async function middleware(req: NextRequest) {
const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
if (!token) {
return NextResponse.redirect(new URL("/login", req.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard/:path*"],
};
5. 환경 변수 설정
.env.local 파일을 생성하여 다음과 같이 설정합니다:
NEXTAUTH_SECRET=your_secret_key NEXT_PUBLIC_API_URL=http://localhost:8080/api
6. 프로젝트 디렉토리 구조
Next.js 15 디렉토리 구조
/frontend │── src/ │ ├── app/ │ │ ├── layout.tsx │ │ ├── page.tsx │ │ ├── dashboard/ │ │ │ ├── page.tsx │── components/ │── lib/ │ ├── apiClient.ts │── middleware.ts │── pages/api/auth/[...nextauth].ts │── styles/ │── .env.local
Spring Boot 3.3 디렉토리 구조
/backend │── src/ │ ├── main/java/com/example/demo/ │ │ ├── controller/ │ │ ├── service/ │ │ ├── security/ │ │ ├── repository/ │ │ ├── model/ │── resources/ │ ├── application.properties
NextAuth.js → Spring Boot API와 연동하여 JWT 또는 세션 기반 인증 구현
Axios Instance + React Query → API 호출을 최적화하고 캐싱 관리
Middleware → 보호된 페이지 접근을 제한
환경 변수 설정 → API URL 및 보안 정보 관리
2. Spring Boot 3.3 백엔드 설정
프로젝트 생성
Spring Boot 프로젝트를 생성할 때, Spring Web, Spring Security, Spring Boot JPA, MySQL Driver 등의 의존성을 추가합니다.
application.properties 설정
server.port=8080 spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=yourpassword spring.jpa.hibernate.ddl-auto=update spring.security.jwt.secret=your_jwt_secret_key spring.security.jwt.expiration=3600000
Security 설정 (SecurityConfig.java)
package com.example.demo.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
)
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
return http.build();
}
}
로그인 API (AuthController.java)
package com.example.demo.controller;
import com.example.demo.model.LoginRequest;
import com.example.demo.model.LoginResponse;
import com.example.demo.service.AuthService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController {
private final AuthService authService;
@PostMapping("/login")
public ResponseEntity<LoginResponse> login(@RequestBody LoginRequest request) {
return ResponseEntity.ok(authService.authenticate(request));
}
}
JWT 인증 서비스 (AuthService.java)
package com.example.demo.service;
import com.example.demo.model.LoginRequest;
import com.example.demo.model.LoginResponse;
import org.springframework.stereotype.Service;
@Service
public class AuthService {
public LoginResponse authenticate(LoginRequest request) {
// 실제 인증 로직 구현 (DB 조회 후 검증)
String token = "mock-jwt-token"; // JWT 생성 로직 적용 필요
return new LoginResponse(token);
}
}














댓글 ( 0)
댓글 남기기