Skip to content

Commit

Permalink
Merge pull request #208 from Team-Smeme/sohyeon_#198
Browse files Browse the repository at this point in the history
[REFACTOR] RestClient 사용 및 그 외
  • Loading branch information
thguss authored Feb 27, 2024
2 parents 6c2e655 + ce2b3a6 commit 316c512
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 76 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ buildscript {

plugins {
id 'java'
id 'org.springframework.boot' version '3.0.1'
id 'io.spring.dependency-management' version '1.1.0'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
}

allprojects {
Expand Down
85 changes: 35 additions & 50 deletions smeem-api/src/main/java/com/smeem/api/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;


@Configuration
Expand All @@ -21,62 +23,45 @@ public class SecurityConfig {
private final JwtAuthenticationFilter jwtAuthenticationFilter;
private final CustomJwtAuthenticationEntryPoint customJwtAuthenticationEntryPoint;

private static final String[] AUTH_WHITELIST = {
"/api/v2/auth",
"/api/v2/test",
"/api/beta/token",
"/error",
"/favicon.ico",
"/api/v2/members/nickname/check",
"/api/v2/goals",
"/api/v2/goals/{type}"
};

private static final String[] AUTH_WHITELIST_SWAGGER = {
"/v3/api-docs/**",
"/swagger-ui/**",
"/swagger-ui.html",
"/docs/**"
};

@Bean
@Profile({"dev", "local"})
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf().disable()
.formLogin().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(customJwtAuthenticationEntryPoint)
.and()
.authorizeHttpRequests()
.requestMatchers(AUTH_WHITELIST).permitAll()
.requestMatchers(AUTH_WHITELIST_SWAGGER).permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.build();
public SecurityFilterChain filterChainDev(HttpSecurity http) throws Exception {
permitSwaggerUri(http);
setHttp(http);
return http.build();
}

@Bean
@Profile("prod")
public SecurityFilterChain filterChainProd(HttpSecurity http) throws Exception {
return http
.csrf().disable()
.formLogin().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(customJwtAuthenticationEntryPoint)
.and()
.authorizeHttpRequests()
.requestMatchers(AUTH_WHITELIST).permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.build();
setHttp(http);
return http.build();
}

private void setHttp(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.sessionManagement(sessionManagement ->
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(exceptionHandling ->
exceptionHandling.authenticationEntryPoint(customJwtAuthenticationEntryPoint))
.authorizeHttpRequests(authorizeHttpRequests ->
authorizeHttpRequests
.requestMatchers(new AntPathRequestMatcher("/api/v2/auth", "POST")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/v2/test")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/v2/goals/{type}")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/v2/goals")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/v2/members/nickname/check")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/favicon.ico")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/error")).permitAll()
.anyRequest().authenticated())
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}

private void permitSwaggerUri(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorizeHttpRequests -> authorizeHttpRequests
.requestMatchers(new AntPathRequestMatcher("/v3/api-docs/**")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/swagger-ui/**")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/docs/**")).permitAll());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.http.HttpStatus;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.METHOD_NOT_ALLOWED;

@RequiredArgsConstructor
@Getter
Expand All @@ -15,6 +16,11 @@ public enum FcmFailureCode implements FailureCode {
*/
INVALID_REQUEST_PATTERN(BAD_REQUEST, "잘못된 요청 형식입니다."),
INVALID_REQUEST_MESSAGE(BAD_REQUEST, "잘못된 fcm 요청입니다."),

/**
* 405 METHOD NOT ALLOW
*/
INVALID_REQUEST_URI(METHOD_NOT_ALLOWED, "외부 API 요청에 실패했습니다"),
;

private final HttpStatus status;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.smeem.common.code.failure.FailureCode;
import com.smeem.common.code.failure.FcmFailureCode;
import lombok.Getter;
import org.springframework.http.HttpStatusCode;

@Getter
public class FcmException extends RuntimeException {
Expand All @@ -13,4 +14,9 @@ public FcmException(FcmFailureCode failureCode) {
super("[FcmException] : " + failureCode.getMessage());
this.failureCode = failureCode;
}

public FcmException(FcmFailureCode failureCode, HttpStatusCode statusCode) {
super("[FcmException] : " + statusCode + ", " + failureCode.getMessage());
this.failureCode = failureCode;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,18 @@
import com.smeem.external.firebase.dto.request.MessagePushServiceRequest;
import lombok.val;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpStatusCode;
import org.springframework.stereotype.Service;

import com.google.auth.oauth2.GoogleCredentials;

import lombok.RequiredArgsConstructor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.springframework.web.client.RestClient;

import static com.smeem.common.code.failure.FcmFailureCode.INVALID_REQUEST_MESSAGE;
import static com.smeem.common.code.failure.FcmFailureCode.INVALID_REQUEST_PATTERN;
import static com.smeem.common.code.failure.FcmFailureCode.*;
import static org.springframework.http.HttpHeaders.ACCEPT;
import static org.springframework.http.HttpHeaders.AUTHORIZATION;
import static org.springframework.http.MediaType.APPLICATION_JSON;

@Service
@RequiredArgsConstructor
Expand All @@ -34,18 +33,21 @@ public class FcmService {
private final ValueConfig valueConfig;

public void pushMessage(final MessagePushServiceRequest request) {
try {
val fcmRequest = new Request.Builder()
.url(valueConfig.getFIREBASE_API_URI())
.post(RequestBody.create(makeMessage(request), MediaType.get("application/json; charset=utf-8")))
.addHeader(AUTHORIZATION, "Bearer " + getAccessToken())
.addHeader("Accept", "application/json; UTF-8")
.build();
val client = new OkHttpClient();
client.newCall(fcmRequest).execute();
} catch (Exception exception) {
throw new FcmException(INVALID_REQUEST_MESSAGE);
}
val restClient = RestClient.create();
restClient.post()
.uri(valueConfig.getFIREBASE_API_URI())
.contentType(APPLICATION_JSON)
.body(makeMessage(request))
.header(AUTHORIZATION, "Bearer " + getAccessToken())
.header(ACCEPT, "application/json; UTF-8")
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError, (fcmRequest, fcmResponse) -> {
throw new FcmException(INVALID_REQUEST_MESSAGE, fcmResponse.getStatusCode());
})
.onStatus(HttpStatusCode::is5xxServerError, (fcmRequest, fcmResponse) -> {
throw new FcmException(INVALID_REQUEST_URI, fcmResponse.getStatusCode());
})
.toBodilessEntity();
}

private String makeMessage(MessagePushServiceRequest request) {
Expand All @@ -57,11 +59,15 @@ private String makeMessage(MessagePushServiceRequest request) {
}
}

private String getAccessToken() throws IOException {
val googleCredentials = GoogleCredentials
.fromStream(new ClassPathResource(valueConfig.getFIREBASE_CONFIG_PATH()).getInputStream())
.createScoped(List.of(valueConfig.getGOOGLE_API_URI()));
googleCredentials.refreshIfExpired();
return googleCredentials.getAccessToken().getTokenValue();
private String getAccessToken() {
try {
val googleCredentials = GoogleCredentials
.fromStream(new ClassPathResource(valueConfig.getFIREBASE_CONFIG_PATH()).getInputStream())
.createScoped(List.of(valueConfig.getGOOGLE_API_URI()));
googleCredentials.refreshIfExpired();
return googleCredentials.getAccessToken().getTokenValue();
} catch (IOException exception) {
throw new FcmException(INVALID_REQUEST_PATTERN);
}
}
}

0 comments on commit 316c512

Please sign in to comment.