1단계: 라이브러리 확인 (build.gradle)
아까 추가하셨겠지만, 혹시 모르니 다시 확인! 없으면 추가하고 코끼리 버튼(Reload) 눌러주세요.
Groovy
dependencies {
// ...
// JWT 라이브러리 (jjwt)
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
}
2단계: 설정 파일에 암호키 숨기기 (application.yml)
src/main/resources/application.yml 파일을 열어서 맨 아래에 비밀키를 적어줍니다. (HS256 알고리즘은 키가 너무 짧으면 에러가 나니, 아주 길게(32글자 이상) 아무 말이나 적어주세요.)
YAML
jwt:
secret: "vmfhalwmehvbqwiurnvwnerviunerwiuvneriwuvnreiuwvneriwuvn" # 아무거나 아주 길게!
3단계: 토큰 공장 가동 (JwtUtil.java)
아까 작성했던 코드와 동일합니다. src/main/java/com/csarena/api/global/util/JwtUtil.java 위치에 정확히 있는지 확인해주세요.
Java
package com.csarena.api.global.util;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.security.Key;
import java.nio.charset.StandardCharsets;
import java.util.Date;
@Component // 스프링 빈 등록
public class JwtUtil {
private final Key key;
private final long expirationTime = 1000 * 60 * 60 * 24; // 24시간 (1일)
// application.yml의 jwt.secret 값을 가져옵니다
public JwtUtil(@Value("${jwt.secret}") String secretKey) {
this.key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
}
public String generateToken(Long userId, String email) {
return Jwts.builder()
.setSubject(String.valueOf(userId)) // 토큰 주인(ID)
.claim("email", email) // 내용물(Payload)
.setIssuedAt(new Date()) // 발행 시간
.setExpiration(new Date(System.currentTimeMillis() + expirationTime)) // 만료 시간
.signWith(key, SignatureAlgorithm.HS256) // 서명 (도장 쾅!)
.compact();
}
}
4단계: 컨트롤러 연결 (AuthController.java)
이제 컨트롤러에서 JwtUtil을 주입받고, 가짜 문자열 대신 진짜 토큰을 발급합니다.
Java
package com.csarena.api.domain.user.controller;
import com.csarena.api.domain.user.dto.SignupRequest;
import com.csarena.api.domain.user.dto.SignupResponse;
import com.csarena.api.domain.user.entity.User;
import com.csarena.api.domain.user.service.UserService;
import com.csarena.api.global.common.dto.ApiResult;
import com.csarena.api.global.util.JwtUtil; // ★ import 확인
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/auth")
public class AuthController {
private final UserService userService;
private final JwtUtil jwtUtil; // ★ 1. 주입 받기
@PostMapping("/signup")
public ResponseEntity<ApiResult<SignupResponse>> signup(@RequestBody @Valid SignupRequest request) {
// 1. 회원가입 진행 (DB 저장)
User newUser = userService.signup(request.getEmail(), request.getPassword(), request.getNickname());
// 2. ★ 진짜 JWT 토큰 발급!
String accessToken = jwtUtil.generateToken(newUser.getId(), newUser.getEmail());
// 3. 응답에 토큰 담기
SignupResponse responseData = SignupResponse.builder()
.userId(newUser.getId())
.email(newUser.getEmail())
.accessToken(accessToken) // "아직_구현_안함" -> accessToken 변수로 교체
.message("회원가입이 완료되었습니다.")
.build();
return ResponseEntity.ok(ApiResult.success(responseData));
}
// ... 나머지 check 메서드들 ...
}
🚀 최종 확인 (Postman)
이제 다시 서버를 켜고 Postman으로 회원가입 요청을 보내보세요.
- 응답 결과:
JSON
{
"success": true,
"data": {
"userId": 1,
"email": "real@test.com",
"accessToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiw...", // ★ 이렇게 엄청 긴 외계어가 나와야 성공!
"message": "회원가입이 완료되었습니다."
}
}
✅ 꿀팁: 나온 토큰(eyJ...)을 복사해서 jwt.io 사이트에 붙여넣어 보세요. 오른쪽 Payload 박스에 우리가 넣은 이메일과 유저 ID가 보이면 완벽하게 성공입니다!
테스트 코드는 토큰 값 자체를 검사하지 않기 때문에(그냥 성공 여부만 보니까), 기존 테스트들도 여전히 통과할 겁니다. (이게 바로 좋은 설계의 장점이죠! 👍)
잘 되시는지 확인 부탁드려요!