UMC 7주차

Simple·2021년 11월 25일
1

UMC 1기 Server

목록 보기
7/9

1. 학습 목표

  1. 인증과 권한 부여(인가)에 대한 지식 습득
  2. 로그인 유지 방법에 대해서 이해 및 적용
  3. DB가 항상 정확하고 일관된 상태를 유지하는 방법

2. 7주차 수업 후기 (선택)

💡 7주차 수업 듣고 느낀점 이야기, 각자 진행상황 공유

3. 실습

📝실습 체크리스트

  • API 20개까지 구현하기
  • API Sheet 작성하기
  • JWT 활용하여 해당하는 모든 API 디벨롭하기
  • Paging 처리를 하여 조회 일부 API 디벨롭하기
  • Transaction 활용하여 API를 디벨롭하기

🔥 트러블 슈팅(실패한 경험도 성장을 위한 경험!)

  • 트러블 슈팅 양식

[ 문제 원인 ] nginx restart가 안된다.

[ 해결 방안 ]

웹서버 에러 - [emerg] bind() to [::]:443 failed (98: Address already in use) | 꿈꾸는섬

[ 참고 자료 ]

  • 트러블 슈팅 양식

[ 문제 원인 ]

bash: ./gradlew: Permission denied

[ 해결 방안 ]

chmod +x gradlew  를 터미널에 입력 한 후, 다시 ./gradlew build 를 실행하면 빌드가 되는 것을 확인 할 수 있다.

[ 참고 자료 ]

  • 트러블 슈팅 양식

[ 문제 원인 ]

ec2의 RAM이 너무 느리다.

[ 해결 방안 ]

swap 을 통해 메모리 할당

[ 참고 자료 ]

https://psychoria.tistory.com/m/717

[ 문제 원인 ] (맥OS로 복습하면서 나타난 에러)The repository 'http://ppa.launchpad.net/certbot/certbot/ubuntu focal Release' does not have a Release file.

[ 해결 방안 ]


sudo apt-add-repository -r ppa:certbot/certbot 로 삭제시켜주면 된다.

[ 참고 자료 ]

https://jamie95.tistory.com/184

5. 핵심 키워드

  • Stateless(무상태성)

    stateless

    :

    server side에

    client와 server의 동작, 상태정보를

    저장하지 않는

    형태, server의 응답이 client와의 세션 상태와 독립적임

    장점 : 서버가 client정보를 저장관리 하지 않으므로

    Scaling이 자유로움

    [예시] (Stateless protocol)

    UDP / HTTP

    : UDP는 TCP와 달리 Client의 세션 상태와 관계 없이 요청에 대한 응답만을 수행하고, server가 client의 정보를 저장하지 않는다.

  • Request Header를 활용한 로그인 방식

    ???

  • 쿠키,세션을 이용한 로그인 방식

    • 사용자가 로그인을 합니다.
    • 서버에서는 계정 정보를 읽어 사용자를 확인한 후, 사용자에게 고유한 ID값을 부여하여 세션 저장소에 저장한 후, 이와 연결되는 Session ID를 발급합니다.
    • 서버는 HTTP 응답 헤더에 발급된 Session ID를 실어 보냅니다. 이후 매 요청마다 HTTP 요청 헤더에 Session ID가 담킨 쿠키를 실어 보냅니다.
    • 서버에서는 쿠키를 받아 세션 저장소에서 대조를 한 후 대응되는 정보를 가져옵니다.
    • 인증이 완료되고 서버는 사용자에 맞는 데이터를 보내줍니다.
    • 장점
      • 사용자의 정보는 세션 저장소에 저장되고, 쿠키는 그 저장소를 통과할 수 있는 출입증 역할을 합니다. 따라서 쿠키가 담긴 HTTP 요청이 도중에 노출되더라도 쿠키 자체에는 유의미한 값을 갖고있지 않아서 쿠키에 사용자 정보를 담아 인증을 거치는 것 보다 안전합니다.
      • 각 각의 사용자는 고유의 Session ID를 발급 받기 때문에 일일이 회원 정보를 확인할 필요가 없어 서버 자원에 접근하기 용이합니다.
    • 단점
      • 쿠키에 사용자 정보를 담아 인증을 거치는 것 보다 안전하지만, 해커가 쿠키를 탈취한 후 그 쿠키를 이용해 HTTP 요청을 보내면 서버는 사용자로 오인해 정보를 전달하게 됩니다. 이를 세션 하이재킹 공격이라고 합니다. 해결책으로는 HTTPS 프로토콜 사용과 세션에 만료 시간을 넣어주는 것 입니다.
      • 서버에서 세션 저장소를 사용하기 때문에 추가적인 저장공간을 필요로 합니다.
  • JWT(Json Web Token)

    • JWT 정보 JWT는 JSON Web Token의 약자로 인증에 필요한 정보들을 암호화시킨 토큰을 말하며, Access Token으로 사용됩니다. JWT를 생성하기 위해서는 Header, Payload, Verify Signature 객체를 필요로 합니다. Header는 토큰의 타입을 나타내는 typ과 암호화할 방식을 정하는 alg로 구성되어 있습니다.
      {
        'alg': 'HS256',
        'typ': 'JWT'
      }

      Payload

      Payload는 토큰에 담을 정보를 포함합니다. 여기서 하나의 정보 조각을 클레임으로 부릅니다. 클레임의 종류로는 Registered, Public, Private로 3가지가 존재합니다. 보통 만료 일시, 발급 일시, 발급자, 권한정보 등을 포함합니다.
      {
        'sub': '1234567890',
        'name': 'John Doe',
        'admin': true,
        'iat': 1516239022
      }

      Verify Signature

      Verify Signature는 Payload가 위변조되지 않았다는 사실을 증명하는 문자열입니다. Base64 방식으로 인코딩한 Header, Payload 그리고 SECRET KEY를 더한 후 서명됩니다.
      HMACSHA256 {
        base64UrlEncode(header) + '.' +
        base64UrlEncode(payload),
        your-256-bit-secret
      }

      완성된 토큰

      https://media.vlpt.us/images/gusdnr814/post/866a40e0-0c1c-4b86-99ba-f4dc1b620de4/image.png Header, Payload는 인코딩될 뿐, 따로 암호화되지 않습니다. 따라서 Header, Payload는 누구나 디코딩하여 확인할 수 있기에 정보가 쉽게 노출될 수 있습니다. 하지만 Verify Signature는 SECRET KEY를 알지 못하면 복호화할 수 없습니다. 만약에 해커가 사용자의 토큰을 훔쳐 Payload의 데이터를 변경하여 토큰을 서버로 보낸다면, 서버에서 Verify Signature을 검사하게 됩니다. 여기서 Verify Signature는 해커의 정보가 아닌 사용자의 정보를 기반으로 암호화되었기 때문에 해커가 변경한 정보로 보낸 토큰은 유효하지 않은 토큰으로 간주합니다. 이를 통해 사용자의 SECRET KEY를 알지 못하면 토큰을 조작할 수 없다는 것을 알 수 있습니다.
    • 인증순서

      인증 순서

      https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F995EC2345B53368912
      • 사용자가 로그인을 합니다.
      • 서버에서는 계정 정보를 읽어 사용자를 확인 후, 사용자의 고유한 ID값을 부여하고 Payload에 정보를 넣습니다.
      • JWT 토큰의 유효기간을 설정합니다.
      • SECRET KEY를 통해 암호화된 Access Token을 HTTP 응답 헤더에 실어 보냅니다.
      • 사용자는 Access Token을 받아 저장한 후, 인증이 필요한 요청마다 토큰을 HTTP 요청 헤더에 실어 보냅니다.
      • 서버에서는 해당 토큰의 Verify Signature를 SECRET KEY로 복호화한 후, 조작 여부, 유효 기간을 확인합니다.
      • 검증이 완료된다면, Payload를 디코딩하여 사용자의 ID에 맞는 데이터를 가져옵니다.
    • 장점
      • 간편합니다. 세션과 쿠키를 이용한 인증은 별도의 세션 저장소의 관리가 필요합니다. 그러나 JWT는 발급 후 검증만 거치면 되기 때문에 추가 저장소가 필요없습니다.
      • 확장성이 뛰어납니다. 토큰 기반으로 하는 다른 인증 시스템에 접근이 가능합니다.
    • 단점
      • JWT는 한 번 발급되면 유효기간이 완료될 때까지는 계속 사용이 가능하며 중간에 삭제가 불가능합니다. 따라서 해커에 의해 정보가 털린다면 대처할 방법이 없습니다.해결책으로는 Refresh Token을 추가적으로 발급하여 해결하는 방식으로 아래에서 설명하겠습니다.
      • Payload 정보가 디코딩하면 누구나 접근할 수 있기에 중요한 정보들을 보관할 수 없습니다.
      • JWT의 길이가 길기 때문에, 인증 요청이 많아지면 서버의 자원낭비가 발생합니다.
    • Access token의 단ㄴ점을 보완하기 위한 Refresh Token

      인증 순서

      https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99DB8C475B5CA1C936
      • 사용자가 로그인을 합니다.

      • 서버에서는 회원 DB에서 값을 비교합니다.

      • 로그인이 완료되면 Access Token, Refresh Token을 발급하여 HTTP 응답 헤더에 실어 보냅니다. 이때 일반적으로 회원 DB에 Refresh Token을 저장해둡니다.

      • 사용자는 Refresh Token은 안전한 저장소에 저장 후, Access Token을 HTTP 요청 헤더에 실어 요청을 보냅니다.

      • Access Token을 검증하여 이에 맞는 데이터를 보냅니다.

      • 시간이 지나 Access Token이 만료됐다고 보겠습니다.

      • 사용자는 이전과 동일하게 Access Token을 HTTP 요청 헤더에 실어 보냅니다.

      • 서버는 Access Token이 만료됨을 확인하고 권한 없음을 신호로 보냅니다.

      • 사용자는 Refresh Token과 Access Token을 HTTP 요청 헤더에 실어 보냅니다.

      • 서버는 받은 Access Token이 조작되지 않았는지 확인한 후, HTTP 요청 헤더의 Refresh Token과 사용자의 DB에 저장되어 있던 Refresh Token을 비교합니다. Token이 동일하고 유효기간도 지나지 않았다면 새로운 Access Token을 발급해줍니다.

      • 서버는 새로운 Access Token을 HTTP 응답 헤더에 실어 다시 API 요청을 진행합니다.

        장점

      • Access Token의 유효 기간이 짧기 때문에, 기존의 Access Token만을 이용한 인증보다 안전합니다.

        단점

      • 구현이 복잡합니다.

      • Access Token이 만료될 때마다 새롭게 발급하는 과정에서 서버의 자원 낭비가 생깁니다.

  • OAuth

    OAuth는 외부서비스의 인증 및 권한부여를 관리하는 범용적인 프로토콜입니다.

  • OAuth 원리와 과정

    현재 범용적으로 사용되고 있는 것은 OAuth 2.0입니다. 2007년에 OAuth 1.0의 초안이 발표되었는데, 네트워크 시장이 커감에 따라 한계가 나타나기 시작했습니다. 그리고 2012년에 OAuth 2.0를 발표하면서 현재까지 사용되고 있습니다. 바뀐 점은 크게 3가지 입니다.

    • 모바일에서도 사용이 용이합니다.

    • 반드시 HTTPS를 사용하므로 보안이 강화됐습니다.

    • Access Token의 만료 기간이 생겼습니다.

      OAuth 2.0의 인증 방식은 4가지가 있지만, 가장 범용적으로 쓰이는 Authorization Code Grant에 대해 알아보겠습니다.

      인증 순서

    • Resource Owner : 일반 사용자

    • Client : 우리가 만든 웹 어플리케이션

    • Authorization Server : 권한 관리 및 Access Token, Refresh Token을 발급해주는 서버

    • Resource Server : OAuth 2.0을 관리하는 서버의 자원을 관리하는 곳

      https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9945F13F5B6EECC02A

    • Resource Owner가 Client에게 인증 요청을 합니다.

    • Client는 Authorization Request를 통해 Resource Owner에게 인증할 수단(Facebook, Google 로그인 url)을 보냅니다.

    • Resource Owner는 해당 Request를 통해 인증을 진행하고 인증을 완료했다는 신호로 Authorization Grant를 url에 실어 Client에게 보냅니다.

    • Client는 해당 권한 증서를 Authorization Server에 보냅니다.

    • Authorization Server는 권한 증서를 확인 후, 유저가 맞다면 Client에게 Access Token, Refresh Token, 그리고 유저의 정보를 발급해줍니다.

    • Client는 해당 Access Token을 DB에 저장하거나 Resource Owner에게 넘깁니다.

    • Resource Owner가 Resource Server에 자원이 필요하면, Client는 Access Token을 담아 Resource Server에 요청합니다.

    • Resource Server는 Access Token이 유효한 지 확인 후, Client에게 자원을 보냅니다.

    • 만일 Access Token이 만료됐거나 위조되었다면, Client는 Authorization Server에 Refresh Token을 보내 Access Token을 재발급 받습니다.

    • 그 후 다시 Resource Server에 자원을 요청합니다.

    • 만일 Refresh token도 만료되었을 경우, Resource Owner는 새로운 Authorization Grant를 Client에게 넘겨야합니다.

  • Paging 처리

    페이징 처리시에는 GET 방식을 사용하며, 페이징 처리시 반드시 필요한 페이지 번호만을 제공해야합니다. 예를 들어 총 51개의 게시물이 존재하고 페이지당 10개의 게시물을 보여주기로 했다면, 6페이지까지 화면에 출력되어야한다는 것입니다.

    그리고 페이징 처리를 확인하기 위해서는 DB에 다량의 데이터를 입력해주는 것이 좋습니다. DB를 입력하는 방법으로는 직접 입력도 가능하지만, 직접 입력하는 것은 번거로운 과정이 아닐 수 없기에 Test를 위한 클래스를 작성하여 반복문으로 데이터를 입력하는 방법을 추천합니다.

    페이징 처리를 위해 사용되는 SQL문에서 LIMIT 키워드를 사용해서 시작데이터와 출력할 데이터의 갯수를 지정할 수 있습니다. 아래의 예시로 보여줄 SQL문은 게시글을 10개씩 출력하고, 첫 번째 페이지를 출력하게하는 SQL문입니다.

    SELECT
      article_no,
      title,
      content,
      writer,
      regdate,
      viewcnt
    FROM tb_article
    WHERE article_no > 0
    ORDER BY article_no DESC, regdate DESC
    LIMIT 0, 10

    출처:

    https://cameldev.tistory.com/57

    [낙타의 개발일기 - CamelDev]

  • Transaction

    • 의미 트랜잭션(Transaction)은 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들을 의미한다.
  • 특징

    1. 트랜잭션은 데이터베이스 시스템에서 병행 제어 및 회복 작업 시 처리되는 작업의 논리적 단위이다.

    2. 사용자가 시스템에 대한 서비스 요구 시 시스템이 응답하기 위한 상태 변환 과정의 작업단위이다.

    3. 하나의 트랜잭션은 Commit되거나 Rollback된다.

  • 성질

    **Atomicity(원자성)**
       

    1. 트랜잭션의 연산은 데이터베이스에 모두 반영되든지 아니면 전혀 반영되지 않아야 한다.

    2. 트랜잭션 내의 모든 명령은 반드시 완벽히 수행되어야 하며, 모두가 완벽히 수행되지 않고 어느하나라도 오류가 발생하면 트랜잭션 전부가 취소되어야 한다.

    Consistency(일관성)

    1. 트랜잭션이 그 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 변환한다.

    2. 시스템이 가지고 있는 고정요소는 트랜잭션 수행 전과 트랜잭션 수행 완료 후의 상태가 같아야 한다.

    Isolation(독립성,격리성)

    1. 둘 이상의 트랜잭션이 동시에 병행 실행되는 경우 어느 하나의 트랜잭션 실행중에 다른 트랜잭션의 연산이 끼어들 수 없다.

    2. 수행중인 트랜잭션은 완전히 완료될 때까지 다른 트랜잭션에서 수행 결과를 참조할 수 없다.

    Durablility(영속성,지속성)

    1. 성공적으로 완료된 트랜잭션의 결과는 시스템이 고장나더라도 영구적으로 반영되어야 한다.

    • 연산 및 상태

    Commit연산

    1. Commit 연산은 한개의 논리적 단위(트랜잭션)에 대한 작업이 성공적으로 끝났고 데이터베이스가 다시 일관된 상태에 있을 때, 이 트랜잭션이 행한 갱신 연산이 완료된 것을 트랜잭션 관리자에게 알려주는 연산이다.

    Rollback연산

    1. Rollback 연산은 하나의 트랜잭션 처리가 비정상적으로 종료되어 데이터베이스의 일관성을 깨뜨렸을 때, 이 트랜잭션의 일부가 정상적으로 처리되었더라도 트랜잭션의 원자성을 구현하기 위해 이 트랜잭션이 행한 모든 연산을 취소(Undo)하는 연산이다.

    2. Rollback시에는 해당 트랜잭션을 재시작하거나 폐기한다.

    트랜잭션의 상태

    https://t1.daumcdn.net/cfile/tistory/999C55345B6D2ED308

    활동(Active) : 트랜잭션이 실행중인 상태

    실패(Failed) : 트랜잭션 실행에 오류가 발생하여 중단된 상태

    철회(Aborted) : 트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태

    부분 완료(Partially Committed) : 트랜잭션의 마지막 연산까지 실행했지만, Commit 연산이 실행되기 직전의 상태

    완료(Committed) : 트랜잭션이 성공적으로 종료되어 Commit 연산을 실행한 후의 상태

profile
몰입하는 개발자

0개의 댓글