Menandatangani dan Mengesahkan JWT dengan python-jose
Enkod dan dekod JWT dengan tuntutan, tempoh luput dan pengesahan khalayak sambil melindungi laluan daripada pengubahsuaian.
Menandatangani dan Mengesahkan JWT dengan python-jose ialah pelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI percuma di CoddyKit. Ini ialah pelajaran 2 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Kem Intensif Pembangunan Bahagian Belakang FastAPI merangkumi sejumlah 4 pelajaran.
Mengapa JWT untuk Pengesahan Tanpa Keadaan
JWT (Token Web JSON) ialah token padat bertandatangan yang membawa tuntutan tentang pengguna. Setelah aplikasi FastAPI Anda mengeluarkan JWT semasa log masuk, klien menghantarnya semula pada setiap permintaan dan Anda mengesahkannya tanpa menyentuh stor sesi.
- Tanpa keadaan — pelayan tidak menyimpan sesi; tandatangan membuktikan ketulenan.
- Boleh mengesan pengubahan — sebarang perubahan pada muatan membatalkan tandatangan.
- Mudah alih — token yang sama berfungsi merentas perkhidmatan yang berkongsi rahsia atau kunci awam.
Dalam pelajaran ini, kita menggunakan python-jose untuk encode (menandatangani) dan decode (mengesahkan) token dengan tuntutan, tamat tempoh dan pengesahan khalayak.
Anatomi JWT
JWT mempunyai tiga bahagian Base64URL yang dicantumkan dengan titik: header.payload.signature.
- Pengepala — algoritma dan jenis token, contohnya
{"alg": "HS256", "typ": "JWT"}. - Muatan — tuntutan (data) seperti
sub,exp,aud. - Tandatangan — cincangan berkunci bagi pengepala + muatan, yang membuktikan token tidak diubah.
Tuntutan standard (berdaftar) yang paling kerap anda gunakan ialah: sub (subjek/id pengguna), exp (expiry), iat (masa dikeluarkan), aud (khalayak), iss (penerbit). Muatan hanya dikodkan, bukan disulitkan, jadi jangan sesekali letakkan rahsia seperti kata laluan di dalamnya.
Memasang dan Mengimport python-jose
Pasang python-jose bersama bahagian belakang kriptografinya supaya algoritma RSA dan EC turut berfungsi:
pip install "python-jose[cryptography]"
Dua fungsi yang akan anda gunakan dengan kerap terdapat dalam jose.jwt: jwt.encode(...) untuk menandatangani dan jwt.decode(...) untuk mengesahkan. Ralat dicetuskan sebagai subkelas JWTError, yang membolehkan anda menangkap semua masalah token dengan kemas.
from jose import jwt
from jose.exceptions import JWTError, ExpiredSignatureError, JWTClaimsError
print("encode:", callable(jwt.encode))
print("decode:", callable(jwt.decode))
print("base error:", issubclass(ExpiredSignatureError, JWTError))Mengekod Token Pertama Anda
Untuk menandatangani token, hantar kamus tuntutan, kunci rahsia dan algoritma. Untuk tandatangan simetri, kami menggunakan HS256, yang menggunakan rahsia yang sama untuk menandatangani dan mengesahkan.
- Letakkan id pengguna dalam
sub— nilainya mestilah rentetan. - Pastikan rahsia itu panjang dan rawak; dalam aplikasi sebenar, muatkannya daripada pemboleh ubah persekitaran.
Hasilnya ialah satu rentetan selamat URL yang boleh anda pulangkan kepada klien.
from jose import jwt
SECRET = "a-very-long-random-secret-string-change-me"
ALGO = "HS256"
claims = {"sub": "user-42", "role": "admin"}
token = jwt.encode(claims, SECRET, algorithm=ALGO)
print(token[:40] + "...")
print("dot count:", token.count("."))Menyahkod dan Mengesahkan
jwt.decode melakukan dua perkara serentak: menyemak tandatangan dan memulangkan tuntutan. Jika tandatangan salah, ia mencetuskan JWTError dan bukannya memulangkan data.
- Hantar algoritma yang sama seperti yang digunakan untuk menandatangani melalui
algorithms=[...]— jangan sesekali mempercayai algoritma yang diisytiharkan dalam pengepala token sahaja. - Penyahkodan yang berjaya bermakna token itu sahih dan tidak diusik.
Contoh di bawah menandatangani token, kemudian mengesahkannya dan membaca semula tuntutan tersebut.
from jose import jwt
SECRET = "a-very-long-random-secret-string-change-me"
token = jwt.encode({"sub": "user-42", "role": "admin"}, SECRET, algorithm="HS256")
payload = jwt.decode(token, SECRET, algorithms=["HS256"])
print("sub:", payload["sub"])
print("role:", payload["role"])Mengesan Pengusikan
Inilah tujuan utama tandatangan. Jika penyerang mengubah satu aksara sahaja dalam muatan, pengesahan akan gagal kerana tandatangan itu tidak lagi sepadan.
- Tangkap
JWTErroruntuk menolak permintaan dengan401 Unauthorized. - Jangan sesekali menyahkod dengan
verify_signature=Falsedalam persekitaran produksi — tindakan itu melangkau pemeriksaan keselamatan sepenuhnya.
Petikan kod ini merosakkan token dan menunjukkan pengesahan mencetuskan ralat.
from jose import jwt
from jose.exceptions import JWTError
SECRET = "a-very-long-random-secret-string-change-me"
token = jwt.encode({"sub": "user-42"}, SECRET, algorithm="HS256")
# Tamper: change the last character of the token
tampered = token[:-1] + ("A" if token[-1] != "A" else "B")
try:
jwt.decode(tampered, SECRET, algorithms=["HS256"])
print("accepted (BAD)")
except JWTError as e:
print("rejected tampered token:", type(e).__name__)Menambahkan Expiry dengan exp
Token hendaklah mempunyai jangka hayat yang pendek. Tuntutan exp ialah cap masa Unix (saat sejak epok, UTC). python-jose menolak token yang telah luput secara automatik semasa penyahkodan dengan mencetuskan ExpiredSignatureError.
- Kira expiry menggunakan UTC yang menyedari zon waktu:
datetime.now(timezone.utc) + timedelta(...). - Token akses biasanya bertahan selama 15-30 minit; token penyegaran bertahan lebih lama.
Anda boleh menghantar datetime atau integer untuk exp — jose menukarkan datetime kepada cap masa untuk anda.
from datetime import datetime, timedelta, timezone
from jose import jwt
SECRET = "a-very-long-random-secret-string-change-me"
expire = datetime.now(timezone.utc) + timedelta(minutes=30)
claims = {"sub": "user-42", "exp": expire}
token = jwt.encode(claims, SECRET, algorithm="HS256")
payload = jwt.decode(token, SECRET, algorithms=["HS256"])
print("exp claim (unix):", payload["exp"])
print("valid for ~30 min")Mengendalikan Token yang Telah Luput
Apabila exp token berada pada masa lampau, jwt.decode mencetuskan ExpiredSignatureError (subkelas JWTError). Kendalikannya secara berasingan supaya anda boleh memberitahu klien untuk menyegarkan token dan bukannya log masuk semula.
- Tangkap
ExpiredSignatureErrordahulu, kemudianJWTErrorumum. - jose menggunakan leeway lalai yang kecil untuk perbezaan jam; anda boleh melaraskannya dengan
options.
Di sini kami mengeluarkan token yang telah pun luput untuk membuktikan pemeriksaan tersebut dicetuskan.
from datetime import datetime, timedelta, timezone
from jose import jwt
from jose.exceptions import ExpiredSignatureError, JWTError
SECRET = "a-very-long-random-secret-string-change-me"
past = datetime.now(timezone.utc) - timedelta(minutes=5)
token = jwt.encode({"sub": "user-42", "exp": past}, SECRET, algorithm="HS256")
try:
jwt.decode(token, SECRET, algorithms=["HS256"])
except ExpiredSignatureError:
print("token expired -> ask client to refresh")
except JWTError:
print("other token error")Pengesahan Khalayak dengan aud
Tuntutan aud (khalayak) menamakan pihak yang sepatutnya menerima token itu — contohnya API anda. Jika anda menetapkannya semasa pengekodan, anda mesti menghantar audience= yang sepadan semasa penyahkodan, atau jose akan mencetuskan JWTClaimsError.
- Mengelakkan token yang dikeluarkan untuk satu perkhidmatan daripada digunakan semula terhadap perkhidmatan lain.
- Jika anda meninggalkan
audience=tetapi token mempunyaiaud, pengesahan akan gagal — hantar nilai itu secara eksplisit.
Contoh ini menandatangani token dengan khalayak dan mengesahkannya semasa penyahkodan.
from jose import jwt
from jose.exceptions import JWTClaimsError
SECRET = "a-very-long-random-secret-string-change-me"
token = jwt.encode(
{"sub": "user-42", "aud": "fastapi-bootcamp-api"},
SECRET, algorithm="HS256",
)
payload = jwt.decode(token, SECRET, algorithms=["HS256"], audience="fastapi-bootcamp-api")
print("aud ok:", payload["aud"])
try:
jwt.decode(token, SECRET, algorithms=["HS256"], audience="some-other-api")
except JWTClaimsError as e:
print("wrong audience rejected:", type(e).__name__)Pembantu Token yang Boleh Digunakan Semula
Dalam projek latihan sebenar, anda membungkus proses menandatangani dan mengesahkan dalam pembantu kecil supaya laluan kekal kemas. Himpunkan tuntutan standard — sub, exp, iat, aud, iss — di satu tempat.
create_access_tokenmembina tuntutan dan menandatangani token.verify_tokenmenyahkod dengan semua pengesahan lalu memulangkan muatan atau mencetuskan ralat.
Modul Python tulen ini tidak mengimport FastAPI, jadi modul ini mudah diuji secara unit secara berasingan.
from datetime import datetime, timedelta, timezone
from jose import jwt
from jose.exceptions import JWTError
SECRET = "a-very-long-random-secret-string-change-me"
ALGO, AUD, ISS = "HS256", "fastapi-bootcamp-api", "auth-service"
def create_access_token(sub, minutes=30):
now = datetime.now(timezone.utc)
claims = {"sub": sub, "iat": now, "exp": now + timedelta(minutes=minutes),
"aud": AUD, "iss": ISS}
return jwt.encode(claims, SECRET, algorithm=ALGO)
def verify_token(token):
return jwt.decode(token, SECRET, algorithms=[ALGO], audience=AUD, issuer=ISS)
t = create_access_token("user-42")
print("verified sub:", verify_token(t)["sub"])Melindungi Laluan FastAPI
Dalam FastAPI, anda memasukkan pengesahan ke dalam kebergantungan. OAuth2PasswordBearer mengambil token daripada pengepala Authorization: Bearer ..., kemudian kebergantungan anda mengesahkannya dan memulangkan pengguna semasa — atau mencetuskan HTTPException(401).
- Mana-mana laluan yang mengisytiharkan
Depends(get_current_user)kini dilindungi. - Tukarkan
JWTErrorkepada 401 yang wajar supaya token yang diusik atau telah luput ditolak dengan status yang betul.
Ini ialah kod rangka kerja, jadi ia berjalan dalam pelayan, bukan dalam penilai kendiri.
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import jwt
from jose.exceptions import JWTError
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")
SECRET, ALGO, AUD = "change-me", "HS256", "fastapi-bootcamp-api"
def get_current_user(token: str = Depends(oauth2_scheme)):
creds_exc = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET, algorithms=[ALGO], audience=AUD)
except JWTError:
raise creds_exc
user_id = payload.get("sub")
if user_id is None:
raise creds_exc
return user_id
@app.get("/me")
def read_me(user_id: str = Depends(get_current_user)):
return {"user_id": user_id}Semakan Pantas: Pengesahan Khalayak
Anda menandatangani token dengan aud="fastapi-bootcamp-api". Panggilan penyahkodan rakan sepasukan kadangkala mencetuskan JWTClaimsError walaupun untuk token yang baru dikeluarkan dan tidak diusik. Apakah punca yang paling berkemungkinan?
Imbas Kembali: Menandatangani dan Mengesahkan JWT
Kini anda boleh mengeluarkan dan mengesahkan JWT dengan python-jose dari awal hingga akhir:
- Kodkan tuntutan dengan
jwt.encode(claims, secret, algorithm="HS256"); pastikansubialah rentetan dan rahsia disimpan dalam pemboleh ubah persekitaran. - Nyahkod dengan
jwt.decode(token, secret, algorithms=[...])dan sentiasa tetapkan senarai algoritma secara eksplisit. - Pengusikan merosakkan tandatangan dan mencetuskan
JWTError— tolak dengan 401. - Expiry melalui
expmencetuskanExpiredSignatureErrorsecara automatik; kendalikannya untuk memulakan penyegaran. - Khalayak melalui
audmesti dipadankan denganaudience=semasa penyahkodan, atau anda akan menerimaJWTClaimsError. - Dalam FastAPI, lakukan pengesahan dalam kebergantungan
Depends(get_current_user)dan tukarkan ralat kepadaHTTPException(401).
Seterusnya: token penyegaran dan kunci tandatangan yang berputar.
Pelajari Kem Intensif Pembangunan Bahagian Belakang FastAPI dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 21
- Pelajaran
- 84
Soalan Lazim
Adakah pelajaran “Menandatangani dan Mengesahkan JWT dengan python-jose” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI, termasuk “Menandatangani dan Mengesahkan JWT dengan python-jose”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Kem Intensif Pembangunan Bahagian Belakang FastAPI merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Menandatangani dan Mengesahkan JWT dengan python-jose”?
Enkod dan dekod JWT dengan tuntutan, tempoh luput dan pengesahan khalayak sambil melindungi laluan daripada pengubahsuaian. Anda berlatih Kem Intensif Pembangunan Bahagian Belakang FastAPI menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Kem Intensif Pembangunan Bahagian Belakang FastAPI?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 4.
Berapa lamakah pelajaran “Menandatangani dan Mengesahkan JWT dengan python-jose” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI ini?
Ya. Setiap pelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Aliran Kata Laluan OAuth2 dan Pengeluaran Token
- Menandatangani dan Mengesahkan JWT dengan python-jose
- Token Segar Semula dan Putaran Token
- Keizinan Berasaskan Skop dan Pengawal Peranan