JWT(Json Web Token)-2021.12.02


JWTとは?

  • ネットワークまたはモバイルデバイスは、ユーザ認証のための暗号化トークンである.
  • Json形式でユーザーのプロパティを保存します.
  • 2.JWTトークンの構成


    ヘッダ、ロード、署名の3つの部分から構成されています.(ポイント分割)

  • header:トークンタイプ、ハッシュ暗号化アルゴリズム

  • ペイロード:情報を含む空間(一対のname:valueからなる)
    ペイロードの属性をClaim Setと呼びます.(クライアントとサーバ間の交換値からなる)

  • signature:点を区切り、署名ヘッダー、およびロードされた文字列の値
    ヘッダで定義されたアルゴリズムのようにSECRET KEYを用いてBase 64 URL−Safeとして符号化する.

  • ヘッダ,負荷値は符号化のみであり,単独で暗号化されていないため,重要な情報が入ると容易に露出する.
    しかし署名についてはSECRET KEYを知らないと解読できない.

  • ハッシュ暗号化方式を使用するため、パスワードを平文に変換することはできません.また,ハッシュ暗号化を行うと,1文字を変えるだけでパスワードゲートが全く異なる.したがって,負荷の情報を意図的に変更して要求すると,検証中にも発見される.

  • 認証方式は、受信トークンのヘッダとペイロードの文字列がSECRET KEYで暗号化された値が受信トークンの署名値と異なる場合、ペイロードまたはヘッダの情報が変更され、サーバは承認しません.
  • 3.JWT認証の原理



  • ユーザ登録後、サーバに登録情報(ID、PW)を送信する.

  • サーバは、メンバー情報を含むDBをクエリし、そのユーザが存在するかどうかを決定します.

  • サーバーが登録されたユーザーとして確認された場合は、「トークン」が発行されます.

  • ユーザ(クライアント)は、受信したトークンを保存します.

  • データ要求時にサーバに送信されるトークン.

  • サーバは、トークン情報が正しく検証されているかどうかを確認します.

  • 検証が完了すると、要求されたデータが送信されます.
  • =>サーバは、セッション/Cookieのようにリポジトリを必要としません.

    4.JWTのメリットとデメリット


  • 長所
  • は、追加のストレージを必要とせず、サーバの拡張、メンテナンス、およびコスト削減を容易にします.
  • は優れた拡張性を有する.トークンベースの他の認証システムにアクセスできます.
  • FacebookとGoogleのログインはトークンベースです.

  • 短所
  • がクライアントに一度に発行するJWTについては、取り返しがつかない.サーバ側には個別に格納されていないため、一度に発行されたトークンは有効期間が終了するまで使用できます.
    =>Access Tokenが盗まれた場合、セキュリティは脆弱です.
  • ソリューションは、既存のAccess Tokenの有効期間を非常に短く設定し、有効期間がやや長いRefresh Tokenを再発行します.そのため、Refresh TokenはAccess Tokenが期限切れになったときに再発行する鍵になります!
  • Payloadの情報は限られています.ペイロードは単独で暗号化されていないため、重要な情報を入れることはできません.
  • JWT長.そのため、検証が必要なリクエストが多ければ多いほど、サーバのリソースが浪費されます.
  • 5.JWTの実施例


    5-1. コイン発行プロセス

    # 로그인 성공할때 토큰 생성
    @app.route('/api/login', methods=['POST'])
    def sign_in():
        id_receive = request.form['username_give'] #사용자가 입력한 ID
        pw_receive = request.form['password_give'] #사용자가 입력한 PW
    
        result = db.userdb.find_one({'id': id_receive, 'pw': pw_receive}) #DB에서 사용자 찾기
    
        if result is not None: #사용자가 존재한다면 토큰 발급
            payload = { #JWT payload에 들어갈 부분을 name / value 형식으로 지정해주기
                'id': id_receive, #사용자 ID를 payload에 담기
                'exp': datetime.utcnow() + timedelta(seconds=60 * 60 * 24)  # 유효기간 설정, 24시간으로 설정함.
            }
    
            token = jwt.encode(payload, SECRET_KEY, algorithm='HS256') # HASH-256 방식으로 암호화, 토큰 발급
            
            return jsonify({'result': 'success', 'token': token}) # 사용자에게 토큰 전달
        else: #사용자가 존재하지 않는다면 에러 메세지 응답
            return jsonify({'result': 'fail', 'msg': '아이디/비밀번호가 일치하지 않습니다.'})
    paylod-登録済みターゲットタイプ
  • に登録されたクレームは、決定されたデータ型であり、選択的に記入することができる.
    上記の例ではexpのみを使用します.
    JWTの長さを簡潔にするためにkeyは3長さです.
    subは通常、独自の値を適用します.
  • iss:トークン発行者(発行者)
  • sub:トークンタイトル(トピック)
  • および:ターゲット(視聴者)
  • exp:トークンの有効期限(有効期限切れ)は、NumericDate形式で提供する必要があります.ex)1480884914370
  • nbf:トークンがアクティブ化されていない日付(notbefore)
  • nbf:トークンがアクティブ化されていない日付(notbefore)
  • jti:JWTトークン識別子(JWT ID)、重複防止、
  • 使い捨てトークン(Access Token)等

    5-2. トークン検証プロセス

  • ユーザが受信したトークンを検証すると、ペイロード中にDBにユーザIDが問い合わされる.
    データベースにユーザ情報が存在する場合、要求されたデータは、メンバーが正しいため、応答メッセージ
  • に返される.
    @app.route('/')
    def home():
        token_receive = request.cookies.get('mytoken') #사용자에게서 토큰을 받음
    
        try:
            payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256']) #받은 토큰 검증
            user_info = db.userdb.find_one({'id': payload['id']})
            if user_info is not None:
                postdata = list(db.cafelist.find({}, {'_id': False}))
    
            return render_template("layout_postlist.html", postdata=postdata) #요청 데이터 응답
    
        except jwt.ExpiredSignatureError: # 유효기간 만료 시 응답
            return redirect(url_for("login", msg="로그인 시간이 만료되었습니다."))
        except jwt.exceptions.DecodeError: # 페이로드 값이 다를 때의 응답
            return redirect(url_for("login", msg="로그인 정보가 존재하지 않습니다."))