init: first commit
This commit is contained in:
commit
8e3e4daaef
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.idea
|
||||||
|
venv
|
||||||
|
__pycache__
|
3
controllers/JWT.py
Normal file
3
controllers/JWT.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import secrets
|
||||||
|
|
||||||
|
secret_key = secrets.token_urlsafe(32)
|
54
main.py
Normal file
54
main.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import uvicorn
|
||||||
|
from passlib.context import CryptContext
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import jwt
|
||||||
|
from fastapi import FastAPI, HTTPException, Request
|
||||||
|
from models.User import User
|
||||||
|
from controllers.JWT import secret_key
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
pwd_context = CryptContext(schemes=["bcrypt"])
|
||||||
|
# 模拟数据库中的用户
|
||||||
|
|
||||||
|
users_db = {
|
||||||
|
"admin": {
|
||||||
|
"username": "admin",
|
||||||
|
"password": pwd_context.hash("admin123")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/login")
|
||||||
|
async def login(user: User):
|
||||||
|
if user.username not in users_db:
|
||||||
|
raise HTTPException(status_code=401, detail="Invalid username")
|
||||||
|
stored_user = users_db[user.username]
|
||||||
|
if not pwd_context.verify(user.password, stored_user["password"]):
|
||||||
|
raise HTTPException(status_code=401, detail="Invalid password")
|
||||||
|
token = await generate_token(user.username)
|
||||||
|
return {"access_token": token}
|
||||||
|
|
||||||
|
|
||||||
|
async def generate_token(username: str) -> str:
|
||||||
|
expiration = datetime.utcnow() + timedelta(minutes=30)
|
||||||
|
payload = {"username": username, "exp": expiration}
|
||||||
|
return jwt.encode(payload, secret_key, algorithm="HS256")
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/users/me")
|
||||||
|
async def get_user_profile(request: Request):
|
||||||
|
cookie = request.headers.get("Cookie")
|
||||||
|
try:
|
||||||
|
payload = jwt.decode(cookie, secret_key, algorithms=["HS256"])
|
||||||
|
username = payload["username"]
|
||||||
|
if username not in users_db:
|
||||||
|
raise HTTPException(status_code=401, detail="Invalid username")
|
||||||
|
return {"username": username}
|
||||||
|
except jwt.DecodeError:
|
||||||
|
raise HTTPException(status_code=401, detail="Invalid token")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
uvicorn.run(app='main:app', host="0.0.0.0", port=80, reload=True)
|
||||||
|
|
6
models/User.py
Normal file
6
models/User.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class User(BaseModel):
|
||||||
|
username: str
|
||||||
|
password: str
|
22
requirements.txt
Normal file
22
requirements.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
annotated-types==0.6.0
|
||||||
|
anyio==4.2.0
|
||||||
|
bcrypt==3.2.2
|
||||||
|
certifi==2023.11.17
|
||||||
|
cffi==1.16.0
|
||||||
|
charset-normalizer==3.3.2
|
||||||
|
click==8.1.7
|
||||||
|
exceptiongroup==1.2.0
|
||||||
|
fastapi==0.109.0
|
||||||
|
h11==0.14.0
|
||||||
|
idna==3.6
|
||||||
|
passlib==1.7.4
|
||||||
|
pycparser==2.21
|
||||||
|
pydantic==2.5.3
|
||||||
|
pydantic_core==2.14.6
|
||||||
|
PyJWT==2.8.0
|
||||||
|
requests==2.31.0
|
||||||
|
sniffio==1.3.0
|
||||||
|
starlette==0.35.1
|
||||||
|
typing_extensions==4.9.0
|
||||||
|
urllib3==2.1.0
|
||||||
|
uvicorn==0.25.0
|
17
test_client.py
Normal file
17
test_client.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
url = "http://127.0.0.1/login"
|
||||||
|
data = {
|
||||||
|
"username": "admin",
|
||||||
|
"password": "admin123"
|
||||||
|
}
|
||||||
|
r = requests.post(url, json=data)
|
||||||
|
token = r.json()["access_token"]
|
||||||
|
headers = {
|
||||||
|
"Cookie": token
|
||||||
|
}
|
||||||
|
print(token)
|
||||||
|
url = "http://127.0.0.1/users/me"
|
||||||
|
r = requests.get(url, headers=headers)
|
||||||
|
print(r.text)
|
Loading…
Reference in New Issue
Block a user