Skip to content

Commit

Permalink
Feat: 임시 토큰 발급
Browse files Browse the repository at this point in the history
API를 호출하기 위한 임시 토큰 발급 API를 구현한다.

Resolves #3
  • Loading branch information
haeyonghahn committed Jul 30, 2023
1 parent a7a342a commit fc0cb2b
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 9 deletions.
1 change: 1 addition & 0 deletions .docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ SPRING_DATASOURCE_USERNAME=${SPRING_DATASOURCE_USERNAME} \
SPRING_DATASOURCE_PASSWORD=${SPRING_DATASOURCE_PASSWORD} \
GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID} \
GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} \
GOOGLE_REDIRECT_URI=${GOOGLE_REDIRECT_URI} \
JWT_SECRET_KEY=${JWT_SECRET_KEY} \
REDIS_HOST=${REDIS_HOST} \
REDIS_PORT=${REDIS_PORT}
Expand Down
2 changes: 2 additions & 0 deletions .docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ services:
SPRING_DATASOURCE_PASSWORD: ${SPRING_DATASOURCE_PASSWORD}
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI}
JWT_SECRET_KEY: ${JWT_SECRET_KEY}
REDIS_HOST: ${REDIS_HOST}
REDIS_PORT: ${REDIS_PORT}
Expand All @@ -34,6 +35,7 @@ services:
SPRING_DATASOURCE_PASSWORD: ${SPRING_DATASOURCE_PASSWORD}
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI}
JWT_SECRET_KEY: ${JWT_SECRET_KEY}
REDIS_HOST: ${REDIS_HOST}
REDIS_PORT: ${REDIS_PORT}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
@Builder
@Schema(description = "사용자 프로필")
public record UserProfileResponse(
@Schema(description = "사용자 순번")
@Schema(description = "사용자 ID")
Long id,
@Schema(description = "사용자 닉네임")
String nickname,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,11 @@ public GroupedOpenApi userGroup() {
.pathsToMatch("/api/v1/user/**")
.build();
}

@Bean GroupedOpenApi tokenGroup() {
return GroupedOpenApi.builder()
.group("Token")
.pathsToMatch("/api/v1/tokens/**")
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public SecurityFilterChain httpSecurity(HttpSecurity http) throws Exception {
.authorizeHttpRequests()
.antMatchers("/").permitAll()
.antMatchers("/health-check").permitAll()
.antMatchers("/api/v1/tokens/temp").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic().disable()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.tags.Tag;

@Tag(name = "헬스체크", description = "was가 작동하고 있는지 확인합니다.")
@RestController
public class HealthCheckController {

@GetMapping("/health-check")
public String healthCheck() {
return "health_check";
return "health-check";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,81 @@

import static org.springframework.http.HttpHeaders.*;

import org.springframework.http.MediaType;
import org.springframework.http.ResponseCookie;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.dnd.gooding.global.dto.ErrorResponse;
import com.dnd.gooding.global.token.api.response.TokenResponse;
import com.dnd.gooding.global.token.service.TokenService;
import com.dnd.gooding.global.util.CookieUtil;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

@Tag(name = "Token", description = "토큰 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/tokens")
public class TokenController {

private final TokenService tokenService;

@PostMapping
@Operation(summary = "임시 토큰을 발급 받는다.")
@SecurityRequirements()
@GetMapping(value = "temp", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<TokenResponse> tempAccessToken() {
String tempAccessToken = tokenService.createAccessToken(1L, "ROLE_USER");
return ResponseEntity
.ok()
.body(new TokenResponse(tempAccessToken));

}

@Operation(summary = "액세스 토큰을 재발급받는다.",
responses = {
@ApiResponse(responseCode = "200", description = "정상처리"),
@ApiResponse(responseCode = "401", description = "유효하지 않은 리프레쉬 토큰입니다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<TokenResponse> refreshAccessToken(
@CookieValue("refreshToken") String refreshToken
) {
String accessToken = tokenService.getAccessTokensByRefreshToken(refreshToken);

return ResponseEntity.ok()
return ResponseEntity
.ok()
.body(new TokenResponse(accessToken));
}

@DeleteMapping
@Operation(summary = "리프레시 토큰과 액세스 토큰을 삭제한다.",
responses = {
@ApiResponse(responseCode = "200", description = "정상처리"),
@ApiResponse(responseCode = "401", description = "쿠키를 찾을 수 없습니다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@DeleteMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> expireRefreshToken(
@CookieValue("refreshToken") String refreshToken
) {
tokenService.deleteRefreshToken(refreshToken);

ResponseCookie emptyCookie = CookieUtil.getEmptyCookie("refreshToken");

return ResponseEntity.noContent()
return ResponseEntity
.noContent()
.header(SET_COOKIE, emptyCookie.toString()).build();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.dnd.gooding.global.token.api.response;

import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "토큰")
public record TokenResponse(
@Schema(description = "액세스 토큰")
String accessToken
) {
}
1 change: 1 addition & 0 deletions src/main/resources/application-security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ spring:
google:
client-id: ${GOOGLE_CLIENT_ID}
client-secret: ${GOOGLE_CLIENT_SECRET}
redirect-uri: ${GOOGLE_REDIRECT_URI}
scope: profile,email
mvc:
static-path-pattern: /static/**

0 comments on commit fc0cb2b

Please sign in to comment.