JWT(Json Web Token)-2021.12.02
JWTとは?
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をクエリし、そのユーザが存在するかどうかを決定します.
サーバーが登録されたユーザーとして確認された場合は、「トークン」が発行されます.
ユーザ(クライアント)は、受信したトークンを保存します.
データ要求時にサーバに送信されるトークン.
サーバは、トークン情報が正しく検証されているかどうかを確認します.
検証が完了すると、要求されたデータが送信されます.
4.JWTのメリットとデメリット
長所
短所
=>Access Tokenが盗まれた場合、セキュリティは脆弱です.
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-登録済みターゲットタイプ
# 로그인 성공할때 토큰 생성
@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': '아이디/비밀번호가 일치하지 않습니다.'})
上記の例ではexpのみを使用します.
JWTの長さを簡潔にするためにkeyは3長さです.
subは通常、独自の値を適用します.
5-2. トークン検証プロセス
データベースにユーザ情報が存在する場合、要求されたデータは、メンバーが正しいため、応答メッセージ
@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="로그인 정보가 존재하지 않습니다."))
Reference
この問題について(JWT(Json Web Token)-2021.12.02), 我々は、より多くの情報をここで見つけました https://velog.io/@bellpro/JWTJson-Web-Token란-2021.12.02テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol