Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
fae13bf
:sparkles: feat: build.gradle ์— JWT ๊ด€๋ จ ์˜์กด์„ฑ ์ถ”๊ฐ€
ojy0903 Jan 23, 2026
ec55155
:sparkles: feat: RefreshToken ์—”ํ‹ฐํ‹ฐ ์ถ”๊ฐ€
ojy0903 Jan 23, 2026
5597335
:sparkles: feat: ๋กœ๊ทธ์ธ ์š”์ฒญ DTO, JWT ํ† ํฐ ๋ฐ˜ํ™˜ DTO ์ถ”๊ฐ€
ojy0903 Jan 23, 2026
97de3e5
:sparkles: feat: RefreshTokenRepository ์ถ”๊ฐ€
ojy0903 Jan 23, 2026
07056d2
:sparkles: feat: ํ† ํฐ ๊ด€๋ จ ์˜ˆ์™ธ ์ฝ”๋“œ ์ถ”๊ฐ€, RefreshTokenException ์ถ”๊ฐ€
ojy0903 Jan 23, 2026
717c534
:bug: fix: RefreshTokenException ์‚ญ์ œ. RefreshTokenRepository ์กฐํšŒ ๊ด€๋ จ ์˜ˆ์™ธ๋Š”โ€ฆ
ojy0903 Jan 23, 2026
7318eb3
:sparkles: feat: ํ† ํฐ ๊ด€๋ จ ์˜ˆ์™ธ ์ฝ”๋“œ AuthErrorCode์— RefreshToken ๋‚ด๋ถ€ email ์กฐํšŒ โ€ฆ
ojy0903 Jan 23, 2026
68f7747
:sparkles: feat: JWT ๊ด€๋ จ ํด๋ž˜์Šค ์ถ”๊ฐ€(JwtTokenProvider, JwtAuthenticationFilโ€ฆ
ojy0903 Jan 23, 2026
a73188a
:sparkles: feat: ํšŒ์›(User) ๋กœ๊ทธ์ธ ์‹œ ์•„์ด๋””๋กœ ์ด๋ฉ”์ผ์„ ์ž…๋ ฅํ•˜๋ฏ€๋กœ, ์ด๋ฅผ ์œ„ํ•œ UserDetails ๊ด€๋ จโ€ฆ
ojy0903 Jan 23, 2026
5c54833
:sparkles: feat: SecurityConfig ์ ‘๊ทผ ์ œํ•œ ๊ด€๋ จ ์ถ”๊ฐ€
ojy0903 Jan 23, 2026
da33fea
:sparkles: feat: GlobalExceptionHandler ๋กœ๊ทธ์ธ ์‹คํŒจ ์‘๋‹ต, JWT ํ† ํฐ invalid ์‘๋‹ต โ€ฆ
ojy0903 Jan 23, 2026
08bf881
:sparkles: feat: ๋กœ๊ทธ์ธ, ํ† ํฐ ์žฌ๋ฐœ๊ธ‰ ๋กœ์ง ํฌํ•จ๋œ Service ํด๋ž˜์Šค ์ถ”๊ฐ€
ojy0903 Jan 23, 2026
86e53bf
:sparkles: feat: ๋กœ๊ทธ์ธ, ํ† ํฐ ์žฌ๋ฐœ๊ธ‰ API ๋ฅผ ์œ„ํ•œ Controller, Swagger Docs ์ถ”๊ฐ€
ojy0903 Jan 23, 2026
e47d34e
:bug: fix: ํ† ํฐ ๊ด€๋ จ ์—๋Ÿฌ์ฝ”๋“œ AuthErrorCode ์˜ code ๊ฐ’ ์ˆ˜์ • ๋ฐ Swagger Docs code ๊ฐ’ ์ˆ˜์ •
ojy0903 Jan 23, 2026
a8701df
:art: style: reissue -> reIssue ๋ฉ”์„œ๋“œ๋ช… ์ˆ˜์ •
ojy0903 Jan 23, 2026
dcbe1b5
:art: style: ์ฝ”๋“œ ์„ค๋ช… ์ฃผ์„ ์ถ”๊ฐ€
ojy0903 Jan 23, 2026
70e3797
:bug: fix: ๋นŒ๋“œ ํ…Œ์ŠคํŠธ ์‹คํŒจ ํ•ด๊ฒฐ์„ ์œ„ํ•œ test ํ™˜๊ฒฝ์šฉ application.yml ์ถ”๊ฐ€(ํ•ด๋‹น ๊ฐ’ ์‹ค์ œ ์‚ฌ์šฉ X)
ojy0903 Jan 23, 2026
83b94b3
:sparkles: feat: @AuthenticationPrincipal ์‚ฌ์šฉ ์˜ˆ์‹œ ExampleController ์— ์ถ”๊ฐ€
ojy0903 Jan 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ dependencies {

// Security
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'

// Database & Cache
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
import com.whereyouad.WhereYouAd.domain.example.presentation.docs.ExampleControllerDocs;
import com.whereyouad.WhereYouAd.global.response.DataResponse;
import com.whereyouad.WhereYouAd.global.response.DefaultIdResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import com.whereyouad.WhereYouAd.global.security.jwt.CustomUserDetails;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

@RestController
Expand All @@ -35,4 +35,21 @@ public ResponseEntity<DataResponse<ExampleResponse>> findById(@PathVariable Long
DataResponse.from(exampleService.findById(id))
);
}

//@AuthenticationPrincipal ์˜ˆ์‹œ ๋ฉ”์„œ๋“œ
//ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ ์ง„ํ–‰ํ•œ ๋’ค,
//Postman์—์„œ Authorization ํƒญ -> Bearer Token -> AccessToken ๊ฐ’ ๋ถ™์—ฌ๋„ฃ๊ธฐ
//or Headers ์—์„œ Authorization ์ถ”๊ฐ€ํ•˜์—ฌ Bearer {AccessToken} ๋ถ™์—ฌ๋„ฃ๊ธฐ
//ํ•ด๋‹น ํšŒ์›์˜ DB์— ์ €์žฅ๋œ Id ๊ฐ’ ๋ฐ˜ํ™˜๋จ.
@GetMapping("/userId")
public String userIdTest(@AuthenticationPrincipal CustomUserDetails customUserDetails) {
return customUserDetails.getUserId().toString();
}

//@AuthenticationPrincipal ์˜ˆ์‹œ ๋ฉ”์„œ๋“œ
//CustomUserDetails ๋‚ด๋ถ€์— getUserId() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํšŒ์›์˜ DB ์ €์žฅ๋œ Id ๊ฐ’ ๋ฐ”๋กœ ๋ฝ‘์•„๋‚ด๊ธฐ๋„ ๊ฐ€๋Šฅ
@GetMapping("/userId2")
public String userIdTest2(@AuthenticationPrincipal(expression = "userId") Long userId) {
return userId.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import com.whereyouad.WhereYouAd.domain.example.application.dto.response.ExampleResponse;
import com.whereyouad.WhereYouAd.global.response.DataResponse;
import com.whereyouad.WhereYouAd.global.response.DefaultIdResponse;
import com.whereyouad.WhereYouAd.global.security.jwt.CustomUserDetails;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

Expand All @@ -30,4 +33,22 @@ public interface ExampleControllerDocs {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "์‹คํŒจ")
})
public ResponseEntity<DataResponse<ExampleResponse>> findById(@PathVariable Long id);

@Operation(
summary = "@AuthenticationPrincipal ์‚ฌ์šฉ๋ฒ• ์˜ˆ์‹œ API",
description = "ํšŒ์›๊ฐ€์ž… -> ๋กœ๊ทธ์ธ ํ›„ AccessToken ์„ ๊ฐ€์ง€๊ณ  ํ•ด๋‹น ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ DB ๋‚ด๋ถ€ ํšŒ์›์˜ Id ๋ฐ˜ํ™˜"
)
@ApiResponses(
@ApiResponse(responseCode = "200", description = "์„ฑ๊ณต")
)
public String userIdTest(@AuthenticationPrincipal CustomUserDetails customUserDetails);

@Operation(
summary = "@AuthenticationPrincipal ์‚ฌ์šฉ๋ฒ• ์˜ˆ์‹œ API",
description = "ํšŒ์›๊ฐ€์ž… -> ๋กœ๊ทธ์ธ ํ›„ AccessToken ์„ ๊ฐ€์ง€๊ณ  ํ•ด๋‹น ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ DB ๋‚ด๋ถ€ ํšŒ์›์˜ Id ๋ฐ˜ํ™˜, CustomUserDetails ๋‚ด๋ถ€ ํŽธ์˜ ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ์˜ˆ์‹œ"
)
@ApiResponses(
@ApiResponse(responseCode = "200", description = "์„ฑ๊ณต")
)
public String userIdTest2(@AuthenticationPrincipal(expression = "userId") Long userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.whereyouad.WhereYouAd.domains.user.application.dto.request;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;

public record LoginRequest(
@NotBlank(message = "์ด๋ฉ”์ผ์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Email(message = "์ด๋ฉ”์ผ ํ˜•์‹์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.")
String email,
@NotBlank(message = "๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
String password
) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.whereyouad.WhereYouAd.domains.user.domain.service;

import com.whereyouad.WhereYouAd.domains.user.application.dto.request.LoginRequest;
import com.whereyouad.WhereYouAd.domains.user.exception.code.AuthErrorCode;
import com.whereyouad.WhereYouAd.domains.user.persistence.entity.RefreshToken;
import com.whereyouad.WhereYouAd.domains.user.persistence.repository.RefreshTokenRepository;
import com.whereyouad.WhereYouAd.global.exception.AppException;
import com.whereyouad.WhereYouAd.global.security.jwt.CustomUserDetailsService;
import com.whereyouad.WhereYouAd.global.security.jwt.JwtTokenProvider;
import com.whereyouad.WhereYouAd.global.security.jwt.dto.TokenResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class AuthService {

private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final JwtTokenProvider jwtTokenProvider;
private final RefreshTokenRepository refreshTokenRepository;
private final CustomUserDetailsService customUserDetailsService;

//์ตœ์ดˆ ๋กœ๊ทธ์ธ์„ ํ†ตํ•ด AccessToken ๊ณผ RefreshToken ๋ฐœ๊ธ‰ ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ
@Transactional
public TokenResponse login(LoginRequest request) {
//email, password ๊ธฐ๋ฐ˜ Spring Security๊ฐ€ ์‚ฌ์šฉํ•  ์ธ์ฆ ๊ฐ์ฒด(AuthenticationToken) ์ƒ์„ฑ
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(request.email(), request.password());

//์‹ค์ œ password ๊ฒ€์ฆ
// authenticate()๊ฐ€ ์‹คํ–‰๋˜๋ฉด CustomUserDetailsService.loadUserByUsername์ด ํ˜ธ์ถœ๋˜์–ด DB์˜ ์œ ์ € ์ •๋ณด์™€ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);

//์ธ์ฆ ์ •๋ณด ๊ธฐ๋ฐ˜ JWT ํ† ํฐ(Access & Refresh) ์ƒ์„ฑ
TokenResponse tokenResponse = jwtTokenProvider.generateToken(authentication);

//RefreshToken ์ €์žฅ -> ์—†์œผ๋ฉด ์ƒ์„ฑ, ์ด๋ฏธ ์žˆ์œผ๋ฉด update
RefreshToken refreshToken = refreshTokenRepository.findByKeyId(request.email())
.map(entity -> entity.updateValue(tokenResponse.refreshToken()))
.orElse(RefreshToken.builder()
.keyId(request.email())
.value(tokenResponse.refreshToken()).
build());

refreshTokenRepository.save(refreshToken);

return tokenResponse;
}

//๊ธฐ์กด AccessToken ๋งŒ๋ฃŒ ์‹œ RefreshToken์„ ํ†ตํ•ด AccessToken & RefreshToken ์„ ์žฌ๋ฐœ๊ธ‰ ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ
@Transactional
public TokenResponse reIssue(String refreshToken) {
jwtTokenProvider.validateToken(refreshToken); //refreshToken ์ž์ฒด์— ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ์‹œ ํ•ด๋‹น ๋ถ€๋ถ„์—์„œ ์˜ˆ์™ธ ๋ฐœ์ƒ

String email = jwtTokenProvider.getSubject(refreshToken); //refreshToken ์—์„œ ์‚ฌ์šฉ์ž email ๊ฐ’ ์ถ”์ถœ

//๊ธฐ์กด์— ํ•ด๋‹น email์˜ RefreshToken ์ด ์žˆ๋Š”์ง€ ์กฐํšŒ
RefreshToken savedRefreshToken = refreshTokenRepository.findByKeyId(email)
.orElseThrow(() -> new AppException(AuthErrorCode.TOKEN_EXPIRED));

//ํ•ด๋‹น ์ €์žฅ๋œ RefreshToken ๊ณผ ์ž…๋ ฅ๋ฐ›์€ RefreshToken ์ด ๋™์ผํ•œ์ง€ ํ™•์ธ
if (!savedRefreshToken.getValue().equals(refreshToken)) {
throw new AppException(AuthErrorCode.INVALID_TOKEN_FORMAT);
}

//์ƒˆ๋กœ์šด ํ† ํฐ ์ƒ์„ฑ์„ ์œ„ํ•ด ์œ ์ € ์ตœ์‹  ์ •๋ณด ์กฐํšŒ
UserDetails userDetails = customUserDetailsService.loadUserByUsername(email);

// Spring Security ์ธ์ฆ ๊ฐ์ฒด ์ƒ์„ฑ
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());

//์ƒˆ๋กœ์šด Access & RefreshToken ์ƒ์„ฑ ๋ฐ ์ €์žฅ
TokenResponse tokenResponse = jwtTokenProvider.generateToken(authentication);
savedRefreshToken.updateValue(tokenResponse.refreshToken());
refreshTokenRepository.save(savedRefreshToken);

//์ƒˆ๋กœ์šด Access & RefreshToken ๋ฐ˜ํ™˜
return tokenResponse;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.whereyouad.WhereYouAd.domains.user.exception.code;

import com.whereyouad.WhereYouAd.global.exception.BaseErrorCode;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
@AllArgsConstructor
public enum AuthErrorCode implements BaseErrorCode {
//ํ† ํฐ ๊ด€๋ จ
TOKEN_EXPIRED(HttpStatus.UNAUTHORIZED, "AUTH_401_2", "ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."),
INVALID_TOKEN_FORMAT(HttpStatus.UNAUTHORIZED, "AUTH_401_3", "์ž˜๋ชป๋œ ํ† ํฐ ํ˜•์‹์ž…๋‹ˆ๋‹ค."),

// ๋กœ๊ทธ์ธ ์‹คํŒจ (๋น„๋ฐ€๋ฒˆํ˜ธ ํ‹€๋ฆผ or ๊ณ„์ • ์—†์Œ)
LOGIN_FAILED(HttpStatus.UNAUTHORIZED, "AUTH_401_1", "์•„์ด๋”” ๋˜๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."),

USER_NOT_FOUND(HttpStatus.NOT_FOUND, "AUTH_401_4", "ํ•ด๋‹น ์ด๋ฉ”์ผ์˜ ํšŒ์›์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.")
;

private final HttpStatus httpStatus;
private final String code;
private final String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.whereyouad.WhereYouAd.domains.user.persistence.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "refresh_tokens")
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RefreshToken {

@Id
private String keyId; //์œ ์ €์˜ ์ด๋ฉ”์ผ(Key)

private String value; //Refresh Token ๊ฐ’(Value)

//ํ† ํฐ ๊ฐฑ์‹  ๋ฉ”์„œ๋“œ
public RefreshToken updateValue(String token) {
this.value = token;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.whereyouad.WhereYouAd.domains.user.persistence.repository;

import com.whereyouad.WhereYouAd.domains.user.persistence.entity.RefreshToken;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.Optional;

public interface RefreshTokenRepository extends JpaRepository<RefreshToken, String> {
@Query("select r from RefreshToken r where r.keyId = :keyId")
Optional<RefreshToken> findByKeyId(@Param("keyId") String keyId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.whereyouad.WhereYouAd.domains.user.presentation;

import com.whereyouad.WhereYouAd.domains.user.application.dto.request.LoginRequest;
import com.whereyouad.WhereYouAd.domains.user.domain.service.AuthService;
import com.whereyouad.WhereYouAd.domains.user.presentation.docs.AuthControllerDocs;
import com.whereyouad.WhereYouAd.global.response.DataResponse;
import com.whereyouad.WhereYouAd.global.security.jwt.dto.TokenResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseCookie;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController implements AuthControllerDocs {

private final AuthService authService;

@PostMapping("/login")
public ResponseEntity<DataResponse<TokenResponse>> login(@RequestBody LoginRequest request) {

TokenResponse tokenResponse = authService.login(request);

ResponseCookie httpOnlyCookie = ResponseCookie.from("refresh_token", tokenResponse.refreshToken())
.httpOnly(true)
// .secure(true) //<-- HTTPS ์—์„œ๋งŒ ์ฟ ํ‚ค ์ „์†กํ•˜๋„๋ก ์„ค์ •
.secure(false) //<-- Postman ํ…Œ์ŠคํŠธ ์šฉ์ด๋ฅผ ์œ„ํ•ด false
.path("/")
.maxAge(60 * 60 * 24 * 7) // 7์ผ
// .sameSite("None") //<-- ํฌ๋กœ์Šค ์‚ฌ์ดํŠธ ์ „์†ก ์ •์ฑ…, ํ”„๋ก ํŠธ์™€ ์—ฐ๋™์‹œ ํ•ด๋‹น ์ฝ”๋“œ ํ™œ์„ฑํ™”
.sameSite("Strict") //<-- ๊ฐœ๋ฐœ or ํ…Œ์ŠคํŠธ or Postman ์„ ์œ„ํ•ด ์ž„์‹œ Strict
.build();

return ResponseEntity.ok()
.header(HttpHeaders.SET_COOKIE, httpOnlyCookie.toString()) //์ƒ์„ฑํ•œ RefreshToken ์ฟ ํ‚ค๋ฅผ ํ—ค๋”์— ์„ค์ •
.header(HttpHeaders.AUTHORIZATION, "Bearer " + tokenResponse.accessToken()) //AccessToken ์„ Authorization ํ—ค๋”์—๋„ ์ถ”๊ฐ€(ํŽธ์˜์‚ฌํ•ญ)
.body(DataResponse.from(tokenResponse));
}

@PostMapping("/reissue")
public ResponseEntity<DataResponse<TokenResponse>> reIssue(
@CookieValue(name = "refresh_token") String refreshToken
)
{
TokenResponse tokenResponse = authService.reIssue(refreshToken);

ResponseCookie httpOnlyCookie = ResponseCookie.from("refresh_token", tokenResponse.refreshToken())
.httpOnly(true)
// .secure(true)
.secure(false)
.path("/")
.maxAge(60 * 60 * 24 * 7) // 7์ผ
// .sameSite("None")
.sameSite("Strict")
.build();

return ResponseEntity.ok()
.header(HttpHeaders.SET_COOKIE, httpOnlyCookie.toString()) //์ƒ์„ฑํ•œ RefreshToken ์ฟ ํ‚ค๋ฅผ ํ—ค๋”์— ์„ค์ •
.header(HttpHeaders.AUTHORIZATION, "Bearer " + tokenResponse.accessToken()) //AccessToken ์„ Authorization ํ—ค๋”์—๋„ ์ถ”๊ฐ€(ํŽธ์˜์‚ฌํ•ญ)
.body(DataResponse.from(tokenResponse));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.whereyouad.WhereYouAd.domains.user.presentation.docs;

import com.whereyouad.WhereYouAd.domains.user.application.dto.request.LoginRequest;
import com.whereyouad.WhereYouAd.global.response.DataResponse;
import com.whereyouad.WhereYouAd.global.security.jwt.dto.TokenResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestBody;

public interface AuthControllerDocs {
@Operation(
summary = "๋กœ๊ทธ์ธ API",
description = "์ด๋ฉ”์ผ, ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ ๋กœ๊ทธ์ธ ์ง„ํ–‰, AccessToken ์„ body ๋กœ ๋ฐ˜ํ™˜ & RefreshToken ์€ ์ฟ ํ‚ค๋กœ ๋ฐ˜ํ™˜"
)
@ApiResponses({
@ApiResponse(responseCode = "200", description = "์„ฑ๊ณต"),
@ApiResponse(responseCode = "401_1", description = "์‹คํŒจ")
})
public ResponseEntity<DataResponse<TokenResponse>> login(@RequestBody LoginRequest request);

@Operation(
summary = "AccessToken ์žฌ๋ฐœ๊ธ‰ API",
description = "AccessToken ๋งŒ๋ฃŒ ์‹œ ์ฟ ํ‚ค์— ์žˆ๋Š” RefreshToken ์„ ์‚ฌ์šฉํ•ด AccessToken & RefreshToken ์„ ์žฌ๋ฐœ๊ธ‰"
)
@ApiResponses({
@ApiResponse(responseCode = "200", description = "์„ฑ๊ณต"),
@ApiResponse(responseCode = "401_2", description = "์‹คํŒจ(RefreshToken ๋งŒ๋ฃŒ, ์žฌ๋กœ๊ทธ์ธ ํ•„์š”)"),
@ApiResponse(responseCode = "401_3", description = "์‹คํŒจ(RefreshToken ์˜ณ์ง€ ์•Š์€ ๊ฐ’)")
})
public ResponseEntity<DataResponse<TokenResponse>> reIssue(@CookieValue(name = "refresh_token") String refreshToken);
}
Loading