[우아한테크코스] 5월 14일 TIL

2 minute read

[Spring] 인증의 과정

Authorization 헤더에 [type] [credentials] (Authorization: Bearer ~~)을 보내 인증한다.

  • type
    Bearer: bearer tokens으로 OAuth 2.0을 사용하기 위함
    Basic: 제일 기본적인 것, base64-encoded
    Digest, HOBA, Mutual 등등이 존재
    참고

  • credentials
    jwt token

    • heder: alg(알고리즘), typ(타입)
    • payload: sub, name(정보), iat(생성시간) -> 토큰에 저장할 값들을 담아둔다. payload의 각각의 값을 claim이라고 한다. base64로 인코딩
    • signature: HMACSHA256으로 인코딩
      이렇게 세개를 .으로 구분해서 만들어진다.
      secret-key를 둬서 암호화, 복호화 키가 같게 대칭으로 키를 관리할 수도 있고(이때 서버에 존재하는 모든 토큰이 같은 키를 가져야 한다.)
      public/private key를 따로 두어 jwt 비대칭 키로 관리할 수도 있다. 생성은 private으로, 복호화는 public으로 하면 된다.

토큰이 어떠한 값을 가지고 있는 것이 좋을지에 대해서 고민해볼 것

[Spring] Dispatcher Servlet

CLIENT -> DISPATCHER SERVLET -> INTECEPTOR -> HANDLER

[web] CORS

교차 출처 리소스 공유, 추가 http 헤더를 사용해 하나의 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 알려주는 것

브라우저는 보안 상의 이유로 교차 출처 http 요청을 제한. XMLHttpRequest와 fetch는 동일 출처 정책을 적용, 웹 애플리케이션은 자신과 같은 출처를 불러올 수 있다.

이 cors는 웹 브라우저에서 해당 정보를 읽는 것이 허용된 출처를 서버에서 설명할 수 있는 새로운 HTTP 헤더를 추가함으로써 동작한다.
CORS 명세: 클라이언트가 OPTIONS 메서드로 사전 전달하여 지원하는 메서드를 요청하고 서버에서 허가가 떨어지면 실제 요청을 보내도록 요구한다. 이때 서버는 클라이언트에게 요청에 인증정보(쿠키, http 인증)를 함께 보내야 한다.

interceptor가 제일 앞에서 잡아버려서 오류가 나는 경우

  1. CORS 설정
  2. 프론트에서 cors 설정
    const path = require('path');
    module.exports = {
     outputDir: path.resolve(__dirname, '../src/main/resources/static/'),
     devServer: {
         proxy: {
             '/': {
                 target: 'http://localhost:8080',
                 ws: true,
                 changeOrigin: true,
             },
         },
     },
    };
    
  • cookie
    웹 요청은 매번 쿠키정보를 포함해 서버로 전송된다.
    최대 4kb
    만료기간 존재
    도메인 단위 접근 제한

  • web storage(local/session) 저장된 데이터가 클라이언트에 존재하지만 서버로 전송되지는 않는다.
    용량의 제한이 없다 (5mb)
    영원히 저장할 수 있다.
    도메인 단위 접근 제한

    • localStorage: 영구, 도메인마다 다른 저장소, 도메인 같으면 다른 브라우저도 접근 가능
    • sessionStorage: 현재 페이지가 브라우징되고 있는 브라우저 컨텍스트 내에서만 유지(브라우저 종료 시 데이터 삭제), 액세스 범위에 제한(같은 도메인 같은 페이지여도 각각의 세션이라 접근 불가)

[TIP] 포트 죽이기

lsof -i :[포트번호]: 포트번호에서 돌고 있는 프로세스 찾기
kill [pid]: pid가 아이디인 프로세스 죽이기

[Spring] deprecated로 지워지는 경우

그 클래스에 들어가면 @Deprecated 어노테이션이 달려있는 것을 볼 수 있다.
이 경우 이제 스프링에서 얘를 사용하지 않겠다고 한 것이고, 이를 대체할 요소도 주석에 적혀져 있다.
이것을 사용하는 것이 장려된다.

[Spring] Spring MVC 구조

  • DispatcherServlet
    req, res를 받아서 원하는 컨트롤러의 메서드로 매핑해주고, 그 처리가 끝나고 view와 같은 결과가 나오면 적당한 결과를 매핑해 반환해주는 아이.
    즉 우리가 비즈니스로직만 만들면 되도록 연결해주는 아이
    servlet WebApplicationContext(controllers, viewResolver, handlerMapping) <–상속– root WebApplicationContext(Services, Repositories)

  • HandlerMapping
    컨트롤러를 찾아주는 기능, 인터페이스로 매핑될 곳을 가지고 있다.

  • HandlerAdapter
    핸들러매핑을 통해 찾은 컨트롤러를 실행하는 기능, 인터페이스를 구현해서 생성
    boolean supports(지원 여부) -> ModelAndView handle(동작 구현)

  • HandlerEnterceptor
    DispatcherServlet의 호출 전후로 요청, 응답 가공하는 필터
    prehandle은 컨트롤러 호출 전 실행, posthandle은 호출 후 실행(ModelAndView 제공됨), afterCompletion은 모든 작업 완료 후 실행

  • ViewResolver
    이름에 따른 뷰를 찾아서 반환

  • 키워드 잡히면 공식문서로 학습하고 넘어갈 것!