在整理筆記的同時發現自己對於 JWT 還是有點模糊
所以打算利用這個機會重新了解這個機制。
建立輸入輸出格式:
# 輸入
# api_models.py
member_register_model = api.model("MembersRegister", {
"username": fields.String,
"password": fields.String,
"email": fields.String
})
# 輸出
201
{ "message": "Username has been used" }, 409
{ "message": "Email has been used" }, 409
Register 邏輯流程:
# member_controller.py
from werkzeug.security import generate_password_hash
from ...models import generate_salt
@member_ns.route("/member/register")
class MemberRegisterAPI(Resource):
@member_ns.expect(member_register_model) # 利用 member_register_model 要求輸入格式
def post(self):
# 利用輸入的 username、email 判斷資料庫中是否已經存在相同資料
if get_member_by_username(member_ns.payload["username"]):
response = {"message": "Username has been used"}
return response, 409
if get_member_by_email(member_ns.payload["email"]):
response = {"message": "Email has been used"}
return response, 409
# 將密碼加鹽後 Hash
salt = generate_salt()
password_hash = generate_password_hash(member_ns.payload["password"]+ salt)
# 利用輸入的資料以及加鹽後的密碼建立一個新的 Member 加到資料庫中
addMember(member_ns.payload["username"], member_ns.payload["email"], password_hash, salt)
return 201
# member_model.py
import secrets
def generate_salt():
return secrets.token_hex(16)
def get_member_by_username(username):
return Member.query.filter_by(username=username).first()
def get_member_by_email(email):
return Member.query.filter_by(email=email).first()
def addMember(username, email, password_hash, salt):
member = Member(username=username, email=email, password_hash=password_hash, salt=salt)
db.session.add(member)
db.session.commit()
測試
因為 HTTP 協議是無狀態的,意思是說後端不清楚是誰發來的請求,所以需要一個驗證的機制。
以往大多是使用 session 來做驗證,隨著網路環境的發展也產生了一些狀況,而 JWT 機制可以解決這些狀況。
Authorization
)中包含 JWT。JWT 組成:
alg
和 typ
,分別代表簽名/加密的算法和令牌類型(通常為 JWT)。iss
(issuer, JWT 簽發者), exp
(expiration time, 過期時間), sub
(subject, 主體, 通常為 user id) 等。.
將它們串聯起來。今天將 Register API 完成,並且重新學習了 JWT 的由來、解決的問題、使用流程、實際內容。
明天將開始時做 JWT 的流程啦!!!