JWT (JSON Web Token)

웹 로그인 구현 방식 중 하나. 서버에서 로그인 사실을 증명하는 암호화된 토큰을 클라이언트로 발행하며, 클라이언트는 해당 토큰을 사용하여 로그인을 증명한다.

· 사용 방법

  • [서버] 토큰 발행

    # 패키지 및 라이브러리 import 
    import jwt
    import hashlib
      
    # jwt 암호화 시 필요한 KEY를 직접 설정한다.
    SECRET_KEY = 'ROLLINGDEV'
      
    @app.route('/sign_in', methods=['POST'])
    def sign_in():
        # 클라이언트로부터 ID, PW를 전달받는다.
        id_receive = request.form['ie_give']
        pw_receive = request.form['pw_give']
      
        # 당 예시에서는 PW를 hash 알고리즘으로 암호화하여 사용한다.
        pw_hash = hashlib.sha256(pw_receive.encode('utf-8')).hexdigest()
        # ID와 암호화된 PW 를 USER 정보가 보관된 DB에서 검색한다.
        result = db.users.find_one({'id': id_receive, 'pw': pw_hash})
      
        # DB 검색결과가 있다면 로그인 성공
        if result is not None:
            # 클라이언트로 보낼 Token 정보를 담는다. 예시에서는 로그인 유지 시간도 함께 사용한다.
            payload = {
             'id': id_receive,
             'exp': datetime.utcnow() + timedelta(seconds=60 * 60 * 24)
            }
            # 토큰을 암호화한다.
            token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
    		# 클라이언트로 result와 token을 전달한다.
            return jsonify({'result': 'success', 'token': token})
        # DB 검색결과가 없다면 로그인 실패
        else:
            # 클라이언트로 result와 메세지를 전달한다.
            return jsonify({'result': 'fail', 'msg': '아이디/비밀번호가 일치하지 않습니다.'})
    
  • [클라이언트] 토큰 요청 및 요청 성공 시 쿠키저장

    function sign_in() {
        // form에 입력된 ID와 PW를 가져온다.
        let id = $("#input-id").val()
        let pw = $("#input-pw").val()
          
        // 일반적으로 이 부분에서 form 입력값의 유효성검사(공란체크 등)를 진행한다.
          
        // 서버 /sign_in 경로로 ID와 PW를 전달한다.
        $.ajax({
            type: "POST",
            url: "/sign_in",
            data: {
                id_give: id,
                pw_give: pw
            },
            // 서버로부터 응답이 정상적으로 도착했을 때 실행할 함수
            success: function (response) {
                // result 메세지가 success일 경우. 즉, 로그인에 성공하여 token을 받은 경우
                if (response['result'] == 'success') {
                    // token값을 'mytoken'이라는 이름으로 cookie에 저장한다.
                    $.cookie('mytoken', response['token'], {path: '/'});
      
                    alert('로그인 완료!')
                    window.location.href = '/'
                } else {
                    // 로그인이 안되면 에러메시지를 띄웁니다.
                    alert(response['msg'])
                }
            }
        })
    }
    
  • [클라이언트] 쿠키삭제

    function sign_out() {
        $.removeCookie('mytoken', {path: '/'});
        // 일반적으로 이 부분에 Logout 시 메세지 또는 redirect가 들어감
    }
    
  • [서버] 토큰 정보 확인

    @app.route('/temp')
    def temp():
        # 클라이언트 cookie에 저장된 token을 가져온다.
        token_receive = request.cookies.get('mytoken')
        try:
            # 토큰을 복호화한 후 발행했던 토큰의 정보에 접근할 수 있다.
            payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
            payload["id"]
              
            # 일반적으로 이 부분에서 서버사이드의 작업을 진행한다.
            # 게시물 DB를 업데이트한다거나 등등
              
            return jsonify({'msg': '성공'})
        except:
            return redirect(url_for("home"))
    

참조

  • Sparta coding club 웹개발 종합반 플러스 강의
  • https://ko.wikipedia.org/wiki/JSON_%EC%9B%B9_%ED%86%A0%ED%81%B0