From 6444f05640f189682e29b9a1c4d8f6d488c7a762 Mon Sep 17 00:00:00 2001 From: gaze <397334393@qq.com> Date: Sun, 14 Jan 2024 17:09:11 +0800 Subject: [PATCH] init: first commit --- .gitignore | 3 +++ controllers/JWT.py | 3 +++ main.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++ models/User.py | 6 ++++++ requirements.txt | 22 +++++++++++++++++++ test_client.py | 17 +++++++++++++++ 6 files changed, 105 insertions(+) create mode 100644 .gitignore create mode 100644 controllers/JWT.py create mode 100644 main.py create mode 100644 models/User.py create mode 100644 requirements.txt create mode 100644 test_client.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..26d0710 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +venv +__pycache__ diff --git a/controllers/JWT.py b/controllers/JWT.py new file mode 100644 index 0000000..9fc39ff --- /dev/null +++ b/controllers/JWT.py @@ -0,0 +1,3 @@ +import secrets + +secret_key = secrets.token_urlsafe(32) diff --git a/main.py b/main.py new file mode 100644 index 0000000..dab81fe --- /dev/null +++ b/main.py @@ -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") +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 = generate_token(user.username) + return {"access_token": token} + + +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") +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) + diff --git a/models/User.py b/models/User.py new file mode 100644 index 0000000..35a2129 --- /dev/null +++ b/models/User.py @@ -0,0 +1,6 @@ +from pydantic import BaseModel + + +class User(BaseModel): + username: str + password: str diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..56a06ae --- /dev/null +++ b/requirements.txt @@ -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 diff --git a/test_client.py b/test_client.py new file mode 100644 index 0000000..09bc685 --- /dev/null +++ b/test_client.py @@ -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)