diff --git a/src/main/java/com/universe/uni/config/SecurityConfig.java b/src/main/java/com/universe/uni/config/SecurityConfig.java index b432408..3c3d5f8 100644 --- a/src/main/java/com/universe/uni/config/SecurityConfig.java +++ b/src/main/java/com/universe/uni/config/SecurityConfig.java @@ -1,5 +1,8 @@ package com.universe.uni.config; +import com.universe.uni.config.jwt.JwtAuthenticationFilter; +import com.universe.uni.config.jwt.JwtExceptionFilter; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -7,9 +10,9 @@ import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - -import com.universe.uni.config.jwt.JwtAuthenticationFilter; -import com.universe.uni.config.jwt.JwtExceptionFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import lombok.RequiredArgsConstructor; @@ -18,25 +21,49 @@ @RequiredArgsConstructor public class SecurityConfig { - private final JwtAuthenticationFilter jwtAuthenticationFilter; - private final JwtExceptionFilter jwtExceptionFilter; - - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - return http - .cors().and().csrf().disable() - .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - .formLogin().disable() - .authorizeRequests() - .antMatchers("/swagger-ui.html", "/swagger-ui/**", "/auth/*", "/status/uni/*").permitAll() - .and() - .authorizeRequests() - .antMatchers("/api").authenticated() - .anyRequest().permitAll() - .and() - .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) - .addFilterBefore(jwtExceptionFilter, JwtAuthenticationFilter.class) - .build(); - } + private static final String[] PERMITTED_URL = { + "/swagger-ui.html", + "/swagger-ui/**", + "/swagger-resources/**", + "/auth/*", + "/status/uni/*" + }; + + private final JwtAuthenticationFilter jwtAuthenticationFilter; + private final JwtExceptionFilter jwtExceptionFilter; + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + return http + .formLogin().disable() + .httpBasic().disable() + .csrf().disable() + .cors().configurationSource(corsConfigurationSource()) + .and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .authorizeRequests() + .antMatchers(PERMITTED_URL).permitAll() + .and() + .authorizeRequests() + .antMatchers("/api").authenticated() + .anyRequest().permitAll() + .and() + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) + .addFilterBefore(jwtExceptionFilter, JwtAuthenticationFilter.class) + .build(); + } + + @Bean + public CorsConfigurationSource corsConfigurationSource() { + CorsConfiguration configuration = new CorsConfiguration(); + configuration.addAllowedOrigin("http://uni-sparkle.kro.kr"); + configuration.addAllowedOrigin("http://localhost:8080"); + configuration.addAllowedHeader("*"); + configuration.addAllowedMethod("*"); + configuration.setAllowCredentials(true); + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + return source; + } } diff --git a/src/main/java/com/universe/uni/config/SwaggerConfig.java b/src/main/java/com/universe/uni/config/SwaggerConfig.java index 9efef57..6406f1d 100644 --- a/src/main/java/com/universe/uni/config/SwaggerConfig.java +++ b/src/main/java/com/universe/uni/config/SwaggerConfig.java @@ -1,5 +1,7 @@ package com.universe.uni.config; +import io.swagger.v3.oas.annotations.ExternalDocumentation; + import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @@ -14,7 +16,7 @@ @OpenAPIDefinition( servers = { @Server(url = "http://uni-sparkle.kro.kr", description = "개발 배포 주소"), - @Server(url = "http://localhost/8080", description = "로컬 환경 주소") + @Server(url = "http://localhost:8080", description = "로컬 환경 주소") }, info = @Info( title = "Sparkle API", @@ -23,9 +25,10 @@ ) ) @SecurityScheme( - name = "Authorization", - type = SecuritySchemeType.APIKEY, - in = SecuritySchemeIn.HEADER + name = "Authorization", + type = SecuritySchemeType.HTTP, + scheme = "Bearer", + in= SecuritySchemeIn.HEADER ) @Configuration public class SwaggerConfig { diff --git a/src/main/java/com/universe/uni/controller/AuthController.java b/src/main/java/com/universe/uni/controller/AuthController.java index 73b82bd..daaec49 100644 --- a/src/main/java/com/universe/uni/controller/AuthController.java +++ b/src/main/java/com/universe/uni/controller/AuthController.java @@ -1,5 +1,15 @@ package com.universe.uni.controller; +import com.universe.uni.controller.docs.AuthControllerContract; +import com.universe.uni.dto.AuthTokenDto; +import com.universe.uni.dto.request.AuthRequestDto; +import com.universe.uni.service.AuthServiceContract; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -7,49 +17,56 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.universe.uni.controller.docs.AuthControllerContract; -import com.universe.uni.dto.AuthTokenDto; -import com.universe.uni.dto.request.AuthRequestDto; -import com.universe.uni.service.AuthServiceContract; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.web.client.RestTemplate; + +import javax.servlet.http.HttpServletRequest; + @Slf4j @RestController @RequiredArgsConstructor @RequestMapping("auth") public class AuthController implements AuthControllerContract { - private final AuthServiceContract authService; + private final AuthServiceContract authService; - @PostMapping("kakao") - @Override - public AuthTokenDto authByKakao(@RequestBody AuthRequestDto request) { - return authService.authWithKakao(request.code()); - } + @PostMapping("kakao") + @Override + public AuthTokenDto authByKakao(@RequestBody AuthRequestDto request) { + return authService.authWithKakao(request.code()); + } - @PostMapping("google") - @Override - public AuthTokenDto authByGoogle(@RequestBody AuthRequestDto request) { - return authService.authWithGoogle(request.code()); - } + @PostMapping("google") + @Override + public AuthTokenDto authByGoogle(@RequestBody AuthRequestDto request) { + return authService.authWithGoogle(request.code()); + } - @PostMapping("apple") + @PostMapping("apple") @Override - public AuthTokenDto authByApple(@RequestBody AuthRequestDto request) { - return authService.authWithAppleUser(request.code()); - } + public AuthTokenDto authByApple(@RequestBody AuthRequestDto request) { + return authService.authWithAppleUser(request.code()); + } - @GetMapping("kakao/callback") + @GetMapping("kakao/callback") @Override - public AuthRequestDto redirectKakaoAuth(@RequestParam(name = "code") String authenticationCode) { - return new AuthRequestDto(authenticationCode); - } + public AuthTokenDto redirectKakaoAuth( + @RequestParam(name = "code") String authenticationCode + ) { + return authService.authWithKakaoCode(authenticationCode); + } - @GetMapping("google/callback") + @GetMapping("google/callback") @Override - public AuthRequestDto redirectGoogleAuth(@RequestParam(name = "code") String authenticationCode) { - return new AuthRequestDto(authenticationCode); - } + public AuthTokenDto redirectGoogleAuth( + @RequestParam(name = "code") String authenticationCode + ) { + return authService.authWithGoogleCode(authenticationCode); + } } diff --git a/src/main/java/com/universe/uni/controller/docs/AuthControllerContract.java b/src/main/java/com/universe/uni/controller/docs/AuthControllerContract.java index 4ce86f5..d575e62 100644 --- a/src/main/java/com/universe/uni/controller/docs/AuthControllerContract.java +++ b/src/main/java/com/universe/uni/controller/docs/AuthControllerContract.java @@ -5,6 +5,7 @@ import com.universe.uni.exception.dto.ErrorResponse; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -17,6 +18,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import javax.servlet.http.HttpServletResponse; + +import java.io.IOException; @Tag(name = "유저 인증", description = "유저 인증 및 로그인/회원가입 api") public interface AuthControllerContract { @@ -123,34 +129,18 @@ AuthTokenDto authByApple( description = "카카오 웹 페이지 로그인을 통해 로그인한 코드를 받을 경우 사용합니다. 일반적으로 사용되지 않는 api", hidden = true ) - @ApiResponses(value = { - @ApiResponse( - responseCode = "200", - description = "인증 후 인증 코드를 담아서 보냅니다", - content = @Content( - mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = AuthRequestDto.class) - ) - ) - }) @GetMapping("kakao/callback") - AuthRequestDto redirectKakaoAuth(@RequestParam(name = "code") String authenticationCode); + AuthTokenDto redirectKakaoAuth( + @RequestParam(name = "code") String authenticationCode + ); @Operation( summary = "구글 인증 Redirect Link", description = "구글 웹 페이지 로그인을 통해 로그인한 코드를 받을 경우 사용합니다. 일반적으로 사용되지 않는 api", hidden = true ) - @ApiResponses(value = { - @ApiResponse( - responseCode = "200", - description = "인증 후 인증 코드를 담아서 보냅니다.", - content = @Content( - mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = AuthRequestDto.class) - ) - ) - }) @GetMapping("google/callback") - AuthRequestDto redirectGoogleAuth(@RequestParam(name = "code") String authenticationCode); + AuthTokenDto redirectGoogleAuth( + @RequestParam(name = "code") String authenticationCode + ); } diff --git a/src/main/java/com/universe/uni/service/AuthService.java b/src/main/java/com/universe/uni/service/AuthService.java index 0fb55a3..00be4e7 100644 --- a/src/main/java/com/universe/uni/service/AuthService.java +++ b/src/main/java/com/universe/uni/service/AuthService.java @@ -2,6 +2,9 @@ import javax.transaction.Transactional; +import com.universe.uni.external.response.GoogleAccessTokenResponse; +import com.universe.uni.external.response.KakaoAuthResponse; + import org.springframework.stereotype.Service; import com.universe.uni.domain.AppleTokenManager; @@ -28,6 +31,13 @@ public class AuthService implements AuthServiceContract { private final UserRepository userRepository; private final AppleTokenManager appleTokenManager; + @Override + @Transactional + public AuthTokenDto authWithKakaoCode(String authenticationCode) { + final KakaoAuthResponse kakaoAuth = kakaoRepository.fetchTokenBy(authenticationCode); + return authWithKakao(kakaoAuth.accessToken()); + } + @Override @Transactional public AuthTokenDto authWithKakao(String accessToken) { @@ -44,6 +54,13 @@ private User registerKakaoUser(KakaoUserResponse kakaoUser) { .build(); } + @Override + @Transactional + public AuthTokenDto authWithGoogleCode(String authenticationCode) { + final GoogleAccessTokenResponse googleAuth = googleRepository.fetchTokenBy(authenticationCode); + return authWithGoogle(googleAuth.idToken()); + } + @Override @Transactional public AuthTokenDto authWithGoogle(String accessToken) { diff --git a/src/main/java/com/universe/uni/service/AuthServiceContract.java b/src/main/java/com/universe/uni/service/AuthServiceContract.java index bef8430..9727f7c 100644 --- a/src/main/java/com/universe/uni/service/AuthServiceContract.java +++ b/src/main/java/com/universe/uni/service/AuthServiceContract.java @@ -5,10 +5,16 @@ import com.universe.uni.dto.AuthTokenDto; public interface AuthServiceContract { - @Transactional + @Transactional + AuthTokenDto authWithKakaoCode(String authenticationCode); + + @Transactional AuthTokenDto authWithKakao(String accessToken); - @Transactional + @Transactional + AuthTokenDto authWithGoogleCode(String authenticationCode); + + @Transactional AuthTokenDto authWithGoogle(String accessToken); @Transactional