DAY78. Front&Back Communication

Davina·2022년 12월 13일
0

서버

서버클라이언트
서비스제공 한다제공 받는다
통신(행위) 요청요청 받는다요청 한다
통신(행위) 응답응답 한다응답 받는다
  • 웹 서버
    • 웹 서비스를 제공하기 위한 서버 컴퓨터 입니다.
    • Apache, IIS, NginX와 같은 웹 서버 소프트웨어를 사용하여 웹 서비스 할 수 있습니다.
  • 웹 애플리케이션 서버
    • 웹 애플리케이션을 제공하기 위한 서버 컴퓨터 입니다.
    • Tomcat, WebLogic, WebSphere와 같은 웹 애플리케이션 서버 소프트웨어를 사용하여 웹 애플리케이션 서비스를 제공할 수 있습니다.
  • 데이터베이스 서버
    • 데이터베이스를 제공하기 위한 서버 컴퓨터 입니다.
    • Oracle, MS-SQL, MySQL과 같은 데이터베이스 소프트웨어를 사용하여 서비스 할 수 있습니다.
  • 파일 전송 서버
    • 대용량의 파일을 빠르게 주고 받기 위한 서버 컴퓨터 입니다.
    • VS-FTPD, IIS와 같은 소프트웨어를 사용하여 서비스 할 수 있습니다.
  • 메일 서버
    • 메일 서비스를 위한 서버 컴퓨터 입니다.
    • Send-mail, Microsoft Exchange Server와 같은 소프트웨어를 사용하여 서비스 할 수 있습니다.
  • 인쇄 서버
    • 공간의 제약을 극복하고 인쇄를 할 수 있도록 하는 서버 컴퓨터 입니다.
    • 인쇄기 제품과 구성에 따라 해당 서비스를 지원하는 다양한 소프트웨어를 사용하여 서비스 할 수 있습니다.

⭐ 하나의 제품에 여러 개발 서버를 나누는 이유는 프론트 개발자와 백엔드 개발자의 포지션을 구분하는 것 처럼 개발 영역을 명확히 하여 관리와 개발을 쉽게 하기 위함이고, 더 나아가서는 서버가 감당해야 할 트래픽의 분산을 위함이고 서버의 장애에 대응하기 위함입니다.

서버 구성과 서버 환경 설정

  • 서버 구성
    • 서버 컴퓨터를 구성하는 관점
    • 서버 컴퓨터의 종류, 서버 컴퓨터의 대수, 네트워크 정책, 서버 수용 인원 예측 등을 구성
  • 서버 환경 설정
    • 구성된 특정 컴퓨터 서버가 서비스를 제공할 수 있도록 환경을 구성하는 과정

⭐ 서버 구성 작업을 진행한 후, 서버가 구성되면 각 컴퓨터 서버(물리 서버)에 서버가 서비스할 목적에 맞는 서버 환경 설정을 진행해야 합니다. 서버 구성 + 서버 환경 설정 작업에 해당하는 서버 셋팅 작업이 완료되면 개발자는 개발한 제품을 연관된 개발, 운영 서버에 ‘배포’하여 웹 서비스 준비를 할 수 있습니다. 이후 클라이언트(고객)는 우리 제품(제공 관점에서 서버)을 이용(요청과 응답)할 수 있습니다.


프론트앤드 & 백앤드 간의 통신

CORS (Cross-Origin Resource Sharing)
추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제

다른 출처의 리소스를 가져오려고 했지만 SOP 때문에 접근이 불가능합니다.
CORS 설정을 통해 서버의 응답 헤더에 ‘Access-Control-Allow-Origin’을 작성하면 접근 권한을 얻을 수 있습니다.

CORS 정책 동작 방식

  • 프리플라이트 요청 (Preflight Request)
    • 실제 요청을 보내기 전, OPTIONS 메서드로 사전 요청을 보내 해당 출처 리소스에 접근 권한이 있는지부터 확인하는 것을 의미합니다. 브라우저는 서버에 실제 요청을 보내기 전에 프리플라이트 요청을 보내고, 응답 헤더의 Access-Control-Allow-Origin으로 요청을 보낸 출처가 돌아오면 실제 요청을 보내게 됩니다. 만약에 요청을 보낸 출처가 접근 권한이 없다면 브라우저에서 CORS 에러를 띄우게 되고, 실제 요청은 전달되지 않습니다.
  • 단순 요청 (Simple Request)
    • 단순 요청은 특정 조건이 만족되면 프리플라이트 요청을 생략하고 요청을 보내는 것을 말합니다.
  • 인증정보를 포함한 요청 (Credentialed Request)
    • 요청 헤더에 인증 정보를 담아 보내는 요청입니다. 출처가 다를 경우에는 별도의 설정을 하지 않으면 쿠키를 보낼 수 없습니다. 민감한 정보이기 때문입니다. 이 경우에는 프론트, 서버 양측 모두 CORS 설정이 필요합니다.

프론트엔드에서 CORS 정책을 우회하는 방법

  • Webpack Dev Server에서 제공하는 proxy 기능을 이용하는 방법
  • http-proxy-middleware 라이브러리를 깐 뒤 해당 라이브러리에서 제공하는 proxy 기능을 이용하는 방법

백엔드에서 CORS Error를 해결하는 방법

애너테이션(@)을 이용해서 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 만 붙여줬습니다. 이렇게 붙이게 되면 모든 도메인, 모든 요청방식에 대해 허용하게 된다는 의미가 됩니다.

글로벌 CORS 설정

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가 보일 것입니다.

백엔드에서 API를 작성하는 방법

https://user-images.githubusercontent.com/58800295/195825100-fef56f69-6527-4a2a-9259-7fc97ae144ba.png

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 형식이고, 이메일이라고 부가 설명을 하고 있습니다.

profile
[많을 (다) 빛날 (빈)] 빛이나는 사람이 되고 싶습니다

0개의 댓글