서버 | 클라이언트 | |
---|---|---|
서비스 | 제공 한다 | 제공 받는다 |
통신(행위) 요청 | 요청 받는다 | 요청 한다 |
통신(행위) 응답 | 응답 한다 | 응답 받는다 |
⭐ 하나의 제품에 여러 개발 서버를 나누는 이유는 프론트 개발자와 백엔드 개발자의 포지션을 구분하는 것 처럼 개발 영역을 명확히 하여 관리와 개발을 쉽게 하기 위함이고, 더 나아가서는 서버가 감당해야 할 트래픽의 분산을 위함이고 서버의 장애에 대응하기 위함입니다.
⭐ 서버 구성 작업을 진행한 후, 서버가 구성되면 각 컴퓨터 서버(물리 서버)에 서버가 서비스할 목적에 맞는 서버 환경 설정을 진행해야 합니다. 서버 구성 + 서버 환경 설정 작업에 해당하는 서버 셋팅 작업이 완료되면 개발자는 개발한 제품을 연관된 개발, 운영 서버에 ‘배포’하여 웹 서비스 준비를 할 수 있습니다. 이후 클라이언트(고객)는 우리 제품(제공 관점에서 서버)을 이용(요청과 응답)할 수 있습니다.
CORS (Cross-Origin Resource Sharing)
추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제다른 출처의 리소스를 가져오려고 했지만 SOP 때문에 접근이 불가능합니다.
CORS 설정을 통해 서버의 응답 헤더에 ‘Access-Control-Allow-Origin’을 작성하면 접근 권한을 얻을 수 있습니다.
Access-Control-Allow-Origin
으로 요청을 보낸 출처가 돌아오면 실제 요청을 보내게 됩니다. 만약에 요청을 보낸 출처가 접근 권한이 없다면 브라우저에서 CORS 에러를 띄우게 되고, 실제 요청은 전달되지 않습니다.@CrossOrigin(origins = "http://example.com")
//허용해야 하는 도메인이 여러 개라면,
//@CrossOrigin(origins = "http://example.com, http://example2.com")
@RestController
@RequestMapping("/account")
public class AccountController {
@RequestMapping(method = RequestMethod.GET, path = "/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
위의 코드는 클래스 수준에서 @CrossOrigin을 추가한 것입니다. 괄호 안의 내용을 조금 더 살펴보겠습니다. origins 뒤로 오고 있는 특정 도메인에 대해서만 허용하고 있음을 확인할 수 있습니다. 이런 식으로 클래스 수준에서 @CrossOrigin을 추가하게 되면 클래스 내부에 작성된retrieve()와 remove() 메소드 둘 다 특정 도메인에 대해 허용하게 됩니다.
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@RequestMapping(method = RequestMethod.GET, path = "/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
class 안의 retrieve() 메소드 위에 @CrossOrigin을 붙여줌으로써 retrieve() 메소드만 허용한 것입니다. 이렇게 작성하면 remove() 메소드는 CORS 설정을 해주지 않았으므로 CORS 정책에서 자유롭지 않습니다. 여기서는 다른 옵션 없이 @CrossOrigin 만 붙여줬습니다. 이렇게 붙이게 되면 모든 도메인, 모든 요청방식에 대해 허용하게 된다는 의미가 됩니다.
package com.codestates.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers().frameOptions().sameOrigin()
.and()
.csrf().disable()
.cors(withDefaults()) // 1. 여기에 집중해주세요!
.formLogin().disable()
.httpBasic().disable()
.authorizeHttpRequests(authorize -> authorize
.anyRequest().permitAll()
);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
// 2. 여기에 집중해주세요!
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET","POST", "PATCH", "DELETE"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("\/**", configuration);
1번 ⇒ CORS 설정을 추가하는 것입니다. .cors(withDefaults())
일 경우, corsConfigurationSource
라는 이름으로 등록된 Bean을 이용합니다.
2번⇒ 이 곳은 CorsConfigurationSource Bean 생성을 통해 구체적인 CORS 정책을 설정하는 곳입니다.
setAllowedOrigins()
을 통해 출처(Origin)에 대해 스크립트 기반의 HTTP 통신을 허용하도록 설정합니다. 현재 *
로되어 있으므로, 모든 출처에 대해 허용하겠다는 의미를 내포하고 있다고 보면 됩니다.setAllowedMethods()
를 통해 파라미터로 지정한 HTTP Method에 대한 HTTP 통신을 허용합니다. 여러분이 익숙한 HTTP method가 보일 것입니다.1번 네모박스 ⇒ http-request로 적혀 있는 부분은, 클라이언트가 이렇게 요청을 보내줘야 한다고 명시하고 있는 부분입니다.
2번 네모박스 ⇒ POST
와 /v11/members
라고 적혀 있습니다. 해당 요청은 POST method
이고, api는 /v11/members
라는 것을 의미하고 있습니다.
밑의 줄은 accept: application/json
이라 적혀 있습니다. 해당 요청을 서버 쪽으로 보낼 때는 request body 부분을 JSON 형식으로 맞춰줄 것을 요구하는 것입니다.
3번 네모박스 ⇒ request body의 예시 입니다. 예시에 작성되어 있는 형식대로 맞춰 POST 요청을 보내라고 요구하고 있다고 이해하면 됩니다.
4번 네모박스 ⇒ request body를 조금 더 자세히 설명하고 있는 부분입니다. 첫 번째 행의 email 필드는 string 형식이고, 이메일이라고 부가 설명을 하고 있습니다.