ABOUT ME

Today
Yesterday
Total
  • 항해99 첫주 WIL
    카테고리 없음 2021. 11. 7. 23:15
    Weekly I Learned(21.11.01-21.11.07)

     

    JWT와 API

    단어 자체로는 들어본 적도 많고 실제로 사용해본 적도 있지만

    정확한 개념이나 쓰임에 대해서는 자세히 알는 못했다.

    이번 프로젝트를 통해서 JWT와 API에 대해 내가 배운 것들을 기록해 보겠다.

     

     

    JWT: JASON Wen Token

    토큰은 우리가 돈을 내고 버스를 타는 권리를 얻듯이 사이트 내에서 사용하는 일종의 권리이다.

    로그인에서의 토큰은 본인 확인 수단이라 할 수 있다.

    로그인을 할 때 id,pw를 입력하면 서버가 확인해서 맞으면 사용자가 유효한 사용자라는 토큰을 발행한다.

    이때 사용되는 토큰이 JWT이다.

    JWT란 JSON 객체를 사용하여 정보를 안정성 있게 전달하는 웹 표준이다.

     

    로그인 기능을 생각해 봤을 때 한번 로그인하고 페이지를 계속 사용할 수 있는 것은 유효한 사용자라는 토큰을

    클라이언트와 서버가 계속 주고받고 있기 때문이다.

    JWT토큰 구성

    aaaaa.bbbb.cccc

    a=header

    b=payload

    c=signature

     

    header: 토큰 타입, 해시 암호와 알고리즘으로 구성되어 있다. 

     - 토큰의 유형(JWT), HMAC, SHA256, RSA와 같은 해시 알고리즘을 나타내는 부분으로 구성

    payload

     - 토큰에 담을 클레임 정보를 포함.  

     - name / value의 한 쌍으로 이루어져 있음.

     - 토큰에는 여러 개의 클레임 들을 넣을 수 있음.

    ***클레임(claim): payload에 담는 정보의 한 조각

        등록된(registered) 클레임, 공개(public) 클레임, 비공개(private) 클레임

    signature

     - secret key를 포함하여 암호화되어있음.

     

    우리가 만든 페이지에서 JWT

    # [로그인 API]
    # id, pw를 받아서 맞춰보고, 토큰을 만들어 발급
    @app.route('/api/login', methods=['POST'])
    def api_login():
    # 로그인
    id_receive = request.form['id_give']
    pw_receive = request.form['pw_give']

     

    #id와 pw를 받아서 해시함수를 사용해서 pw를 암호화해준다.
    pw_hash = hashlib.sha256(pw_receive.encode('utf-8')).hexdigest()

     

    #id, 암호화된 pw로 해당 유저를 찾는다.
    result = db.member.find_one({'id': id_receive, 'pw': pw_hash})

     

    #일치하는 유저를 찾으면 JWT토큰을 만들어 발급
    if result is not None:
    payload = {
    'id': id_receive, #name
    'exp': datetime.utcnow() + timedelta(seconds=60 * 60 * 24) #value# 로그인 24시간 유지 => hour 또는 day
    }

    # jwt 이용 사용자 정보 암호화(단방향 암호화로 개발자가 사용자의 암호를 볼 수 없게 함)
    token = jwt.encode(payload, SECRET_KEY, algorithm='HS256').decode('utf-8')
              header       payload   signature
    return jsonify({'result': 'success', 'token': token})

    # 찾지 못하면
    else:
    return jsonify({'result': 'fail', 'msg': '아이디/비밀번호가 일치하지 않습니다.'})


    API: Application Programming Interface

    API는 프로그램이 실행할 수 있게 명령 목록을 정리하고, 명령을 받으면 응용프로그램과 상호작용하여 명령에 대한 값을 전달하는 것. 프로그램들이 서로 상호작용하는 것을 도와주는 매개체

     

    API의 역할

    1. API는 서버와 데이터베이스에 대한 출입구 역할을 하며, 허용된 사람들에게만 접근성을 부여해준다.

    2. API는 애플리케이션과 기기가 데이터를 원활히 주고받을 수 있도록 돕는 역할을 한다.

    3. API는 모든 접속을 표준화한다.

    REST(Representational State Transfer) API

    - 네트워크를 통해서 컴퓨터들끼리 통신할 수 있게 해주는 아키텍처 스타일

    - 인터넷 식별자(URI)와 HTTP 프로토콜을 기반

    - 데이터 포맷으로 브라우저 간 호환성이 좋은 제이슨(JSON)을 사용

    - 클라이언트-서버 모델로 구축, 정보의 페이로드가 두 지점 사이를 왕복하게 됨.

    - 단일한 인터페이스를 사용하기 때문에 해당 API를 사용하는 애플리케이션들이 동일한 경로를 통해서 접속해야 하고,    그 방식이 단순하게 된다.

     

    REST의 특징

    -Uniform Interface: URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 아키텍처 스타일

    -stateless(무상태성): 작업을 위한 상태 정보를 따로 저장하고 관리하지 않는다. 세션 정보나 쿠키 정보를 별도로 저장하고 관리하지 않기 때문에 API 서버는 들어오는 요청만을 단순히 처리하면 된다. 때문에 서비스의 자유도가 높아지고 서버에서 불필요한 정보를 관리하지 않음으로써 구현이 단순해진다.

    -cacheable(캐시 가능): HTTP라는 기존 웹 표준을 그대로 사용하기 때문에, 웹에서 사용하는 기존 인프라를 그대로 활용이 가능하다. 따라서 HTTP가 가진 캐싱 기능이 적용 가능하다. HTTP 프로토콜 표준에서 사용하는 Last-Modified태그나 E-Tag를 이용하면 캐싱 구현이 가능하다.

    -self-descriptiveness(자체 표현 구조):  REST API 메시지만 보고도 이를 쉽게 이해할 수 있는 자체 표현 구조로 되어 있다

    -client-server구조: REST 서버는 API 제공, 클라이언트는 사용자 인증이나 콘텍스트(세션, 로그인 정보)등을 직접 관리하는 구조로 각각의 역할이 확실히 구분되기 때문에 클라이언트와 서버에서 개발해야 할 내용이 명확해지고 서로 간 의존성이 줄어들게 된다.

    -계층형 구조: REST 서버는 다중 계층으로 구성될 수 있으며 보안, 로드 밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있고 PROXY, 게이트웨이 같은 네트워크 기반의 중간 매체를 사용할 수 있게 한다.

     

    REST API 디자인 가이드
    1. url은 정보의 자원을 표현해야 한다.
    2. 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)로 표현한다.

    @app.route('/delete/login', methods=['POST'])

                   **잘못된 표현 예시: delete는 행위에 대한 표현이기 때문에 들어가서는 안됨.

    @app.route('/login'methods=['POST'])

                   **올바른 예시-자원을 표현하는데 중점을 두어야 한다.


    **POST: 해당 URI를 요청하면 리소스를 생성

    **GET: 해당 리소스 조회, 해당 도큐먼트에 대한 자세한 정보를 가져온다.

    **PUT: 해당 리소스 수정

    **DELETE: 리소스 삭제


    <설계 시 주의할 점>

    • /는 계층 관계를 나타내는 데 사용
    • 마지막 문자로 / 포함하지 않음
    • -은 가독성을 높이는 데 사용
    • _은 URL에 사용하지 않는다.(가독성을 위해)
    • URI 경로에는 소문자가 적합: 대소문자에 따라 다른 리소스로 인식하게 되기 때문
    • 파일 확장자는 URL에 포함시키지 않는다.

     

Designed by Tistory.