From 1e2b08bfc021b48d7997240da836656b30515cbb Mon Sep 17 00:00:00 2001 From: SunFree <7934952@qq.com> Date: Tue, 9 Apr 2024 16:46:19 +0800 Subject: [PATCH] add all --- __pycache__/dependencies.cpython-310.pyc | Bin 2106 -> 2646 bytes __pycache__/main.cpython-310.pyc | Bin 876 -> 1946 bytes __pycache__/test.cpython-310.pyc | Bin 0 -> 2734 bytes dependencies.py | 90 +++++++++--------- internal/__pycache__/__init__.cpython-310.pyc | Bin 125 -> 125 bytes internal/__pycache__/database.cpython-310.pyc | Bin 784 -> 781 bytes internal/__pycache__/models.cpython-310.pyc | Bin 0 -> 970 bytes internal/__pycache__/schemas.cpython-310.pyc | Bin 709 -> 971 bytes internal/database.py | 2 +- internal/models.py | 19 ++++ internal/schemas.py | 11 --- main.py | 45 +++++++-- 12 files changed, 99 insertions(+), 68 deletions(-) create mode 100644 __pycache__/test.cpython-310.pyc create mode 100644 internal/__pycache__/models.cpython-310.pyc create mode 100644 internal/models.py delete mode 100644 internal/schemas.py diff --git a/__pycache__/dependencies.cpython-310.pyc b/__pycache__/dependencies.cpython-310.pyc index 629083140a39a46619874a3c3b69c339dbec6031..1cdf2c5b806a69d57cfc380fcdf65ee0388a0327 100644 GIT binary patch literal 2646 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 Yvj*@)gN+%cVM45yVVRTWboEm8f2t${%>V!Z diff --git a/__pycache__/main.cpython-310.pyc b/__pycache__/main.cpython-310.pyc index afa68d08b997a7d561e8a508d4f2bb3bb4668ae6..737b91546f9427730f8b4ec5c244a05e7eda0dba 100644 GIT binary patch literal 1946 zcmZuxNpBoQ6z-~CW^s=_Ug9Jqz;FPi!Nh<#A%t*}i83r>%N}D?iqz_Ky|LT$GE~)& zcr=z0CRa=RfE?hMzX5-NQysW);x8b9dDY_~cA%wN`qis?%lExkG#Ygazu!(*`af4J z>v!{W{`2tXQylVFoVdkFYGs5GV)itpna%8SZ>LV?GB@*>msMCLtFme-chXwV=(=e= zn`3jt0&ik5AN<1x_h61!PAIq&t50|pY+i%8zQgN$?x{N=Y`)a;VZmte1}yX`pXUot z9XxB|*&=Vk()0ybo)COv5tdMAi7%J;SHS;qk+1wjz`byOiLaLDm-yu!E4cCpMrH*> z*Hn@Lhg3!Qb9HlLs182Zills42)+&94neBBg~$R&SMI<7axQh{ZY0&lR!2AP^?FcOjVV8 zV{%9mGNvYF$M)FfRbG2WF$MMR=(SEB7eYX+T0;pUk1}W#qBS^+f7IOD+k4lf1ag(c zkpkx3f=GY}Y&|!PHjFVA?Qu|1lIqFz?4K_yG_p#rIGIeZXM?U+DW10D?$%tKhF zoOutX&r$71aST$1WwLa=Ttam;fS|?}qjN5V##3FL`KzllZ-rs4KssCOk^v_C@V)oL z-R{P2@80HihqdnrYR;~0+`ir3*$I1_pSQbV`|GXFc02sC)7|a0ci3_)0K*K=I}>KamQ=x>!ZQ1*RC57`Bv5`3yHRrc8)o ziI`V(%8(O^?68qPSWL&1JIIGApIltMG3`6Yj;f69u`{6rxrQupyU7p8%F(sm89|~H zbHtBYGlzf&RQPCBG;kX2b-Fw4?OvnKJ%%}a7UgLUo4L#)Ak8rlV5O*=571lEN61dAU*A>GpQb0S_v z;s3Z2@zM<$X7CPbNW%{L*rDQe+>Dwpj3){*x&9xcHma3Io49#Gxam3A`k&E#g68cm zv+ou~Kv~7y4->B4;$e<$flQHk4R5{d6?Q-L3f01?O;kB^Yo3ZX@UI)J>MAw~FdcbX ztIa-kS}dcR644TgIugb)Ryh+36P7USKUe!cFWWTaaRQPpBstbh9;G+So-2i^IBiFR zfp!LkRAqIssv&nLzjLbuN889L<`@~fZ0I$^CyG__9Zbn#5?Q)^E>2VaqGUt$V>CBR o;S+c%)dgqlTM+-3@Z!0Lz4Szk zpkg&Bs8JyVjTK-1U85z_uxCnWv6jSjOwj>J=!B$BRuRRN+(dg&6PmncS^C}kG0bo{ zhf|Tk2oHw}?(dR~)uzd7Jtkdl?c3H+f#K@E3V8y)c-R-7K7eCA>tT;u?9nb9I9ziA zLgFR(4E!Uw$O#e$*m5UH_PCBq=sCp)+(s_xBT8s;z>sQ)@e2g% diff --git a/__pycache__/test.cpython-310.pyc b/__pycache__/test.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..84329ce2bc7ffe789e541f44f94c1d069a7e0673 GIT binary patch literal 2734 zcmZuzTW=f372cU$E|(NZQ5VaSCCeKpLBhbblASJPA+~Op*5{p?0VI-l95|q){P8{Z#u^pEZm$^xql@pJ7 zNrhF6+=;8n6q`zFtY+q=xSljvBbjE?X70w#WQNU{aXFq%=GYvJJuyF^yuz#J4!eOf zJ_Qno*LWQy3&IsQ&&YuAhFFAs)4X|JVoT!I(K4SAD}45X3ir%{^*K@F^I`=~-rx)8 zr8B~An_V}>D(>QoVinFW@muE(tlfb%pD&BW;s&vFMaK%iZO*?VZvEi%)gKAiaCQ9- z_s#lU{?3loy8AQ6vSsHU54F%yBJv9MT*NxeJsh57sc4bBw3|j*+H&&pLopO7S9y6e zRC@hMC$B&1^`5k!^~F%bmfTf3)FaiR`TW-UNFV<3NvPD*O!5aJltSi9*QMLy>yc1; zGm{A%@jl(_wWZ8tZXZ3>ptrUmkB53AOSO20^U8xziN_fjn0q57WEv)-5758<*f1(V z+kmD%f{v3@qOCC*W1uOwFYHq~rgBab?nKs@{zU#wc7P@jj#BsJgPr#0?Tw!Qk-xdU z_1H%h%HMm`-fo*Qs`LNuzppl1gn0v@`-fp1zqG*gx_Bn~BP{~(M;_^eQ&V&HFNOjZ)QW+<3uc|@kfeQ|)nO-jA z=30LwC2ThPt|5u2I?(k7@k%J!0iAMEX)CXJ(B4)H_=5TtZ}mogBM6w>j<3%luiLJ zHLq>$9F+>UBOvaD{Vmb1F7wg_V5>duj>!>;09jtXpr`iO<{qznkJwhbC##*bpFx!S z`VEOQ=}#a&Y3}Xq{Q+}z0vdCRWCg76fJM@WE-xR7kV85^7M7DJ1*)suR-=6gsDs`y z$bex4&IhJ^Fn8Z1JS^A3eqSgRm-w z?XK_k9&K%RSo@*0acy~hW23#Z6ZEz|Yj=b8zn*lq+ri^bcemHxVRL;cka$;>wj7Dc zAaCL6`Kv3zrO^^=#oHWMfV7O#006vp+Xt{!;Z^i`!*K`&I#c2j_t$EPk}7duRc(0> zmQSi{QXE7|3%O=gUjrUNf6ebtVKM<8(iK3L4Nc$hT-!hgDE_CEI{)n7 z9bF#VW9JMWJd+WnuDp!~EMpZiMJtRUD*V`=7zE^B#T|Q{?oNBV=Xbijt;=%vAtp5* zy61}oGUlE?7{zf=NZzgn{uk??@3wdR58qe!pe{~YtL2$`Qb3F8!e%g`CY%fK9=Qba zykwNH%4;QZ7R0Sm0Tz%70vM$SCi%<>R*N9Jq%JBgtDw0izutzgK5^EZ{R`Zx@M`+J zYGVe4OmfdCcW|p-mE93bf;&~~1 znhMz>Ma+NCDkx206>JNPPOLVUW;Lk%1ZLgVyAq!hlV%bv&Rs}U2){(Svhn~PeR!uN zhC!CGLu`wTZC)+vzT*~L2U5}kae6-BN5_g|9-!C+GPW!-td@* z_;AQ+m_l{YvS1ND6|8x+A|q7H*@fQJ-`oy|!`vBWO6R2>R$`NZat;m}baNX{o6s9a zui#}~V)Jl$e}jrWip4(=ZH1hew`ydOHsR^5!MEYfdJA5y>`>KgUR=&;S4c literal 0 HcmV?d00001 diff --git a/dependencies.py b/dependencies.py index b798ddd..30c16da 100644 --- a/dependencies.py +++ b/dependencies.py @@ -1,74 +1,72 @@ -from datetime import datetime, timedelta - -from fastapi import HTTPException, Depends, status +from datetime import datetime, timedelta, timezone from jose import JWTError, jwt from passlib.context import CryptContext +from fastapi.security import OAuth2PasswordBearer +from fastapi import Depends,HTTPException,status +from internal.models import TokenData,UserInDB,User +from internal.database import execute_query -from internal.database import execute_query, create_connection - -# 设置密码上下文 -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") - -# 随机秘钥 -SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7" -# JWT签名算法变量 +# openssl rand -hex 32 +SECRET_KEY = "e86c54c19962d562dab09081e5a6ce0c8ef49ac9a49cdb7135aa670707bbc894" ALGORITHM = "HS256" -# 设置令牌过期时间 ACCESS_TOKEN_EXPIRE_MINUTES = 30 -# 校验密码方法 -def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) - -# 将密码进行hash -def get_password_hash(password): - return pwd_context.hash(password) - -# 认证用户 -def authenticate_user(username: str, password: str): - query = "SELECT * FROM users WHERE username = %s" - user_data = execute_query(query, (username,)) - if not user_data: - return None - stored_password = user_data["password"] - if not verify_password(password, stored_password): - return None - return user_data +pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") # 创建访问令牌 -def create_access_token(data: dict, expires_delta: timedelta = None): +def create_access_token(data: dict, expires_delta: timedelta): to_encode = data.copy() - if expires_delta: - expire = datetime.utcnow() + expires_delta - else: - expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) + expire = datetime.now(timezone.utc) + expires_delta to_encode.update({"exp": expire}) encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) return encoded_jwt -# 获取当前用户 -async def get_current_user(token: str = Depends(create_connection)): - # 首先定义一个 HTTPException 用于处理认证失败的情况 +async def get_current_user(token: str = Depends(oauth2_scheme)): credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", headers={"WWW-Authenticate": "Bearer"}, ) - try: - # 解码 JWT 令牌,验证签名和有效期 payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) username: str = payload.get("sub") if username is None: raise credentials_exception + token_data = TokenData(username=username) except JWTError: - # 如果 JWT 解码失败,则返回认证异常 raise credentials_exception - - # 根据用户名从数据库中获取用户数据 - user = authenticate_user(username) + user = get_user(username=token_data.username) if user is None: raise credentials_exception - - # 返回获取到的用户数据 + return user + +# 验证用户是否为活跃用户 +async def get_current_active_user(current_user: User = Depends(get_current_user)): + if current_user.disabled: + raise HTTPException(status_code=400, detail="Inactive user") + return current_user + +# 验证密码 +def verify_password(plain_password, hashed_password): + return pwd_context.verify(plain_password, hashed_password) + +# 获取密码哈希 +def get_password_hash(password): + return pwd_context.hash(password) + +# 从数据库获取信息 +def get_user(username: str): + query = "SELECT * FROM users WHERE username = %s" + result = execute_query(query, (username,), fetchall=False) + if result: + return UserInDB(**result) + +# 验证用户密码 +def authenticate_user(username: str, password: str): + user = get_user(username) + if not user: + return False + if not verify_password(password, user.hashed_password): + return False return user diff --git a/internal/__pycache__/__init__.cpython-310.pyc b/internal/__pycache__/__init__.cpython-310.pyc index 1522cfa845643537682ec6c4e5ebf91f1a0bb404..d2544a155b4156d025dcfd5da8537430a60eacb8 100644 GIT binary patch delta 17 Wcmb=e<<95jfgc5Z$%cj_o=mK;gil_gwe^RfMXl72<$}1ie_1R-4S0T5RmF>j*{SR{l)? z(q1`n@|Z3;%^LM&2Qs6LM|Xdo&+8vPho(35V$~|L5@7v0@o){yl0c6A9yO8aG#$mr{8v< z&4MxyM~vhQA9sSFS3F7g8=eSR0B4sfH*2y%iE0kzd05&V<9jfRwagg_e{DJDoSGXAll*@(J0FixgMC8q z6v2ym*O|TM#yCx;9qrv#zT{|;@`o)x$Ju=rL*+A)|E9e-_oEx-ZZyc1a_&oKp|aH9 zy*i%Z1nIpmGWMS`6;>l#Z9uhsv#=3urmGSf5G00G`wsNkbbDK0;h(y7SF&+D7GrUo F{sG}lwu1lw literal 0 HcmV?d00001 diff --git a/internal/__pycache__/schemas.cpython-310.pyc b/internal/__pycache__/schemas.cpython-310.pyc index 592a5dc1f5934afb4fdcd689c5cede3f8f5eeea5..3ea6ffafbdce4e3151ec9860f32a3d3553903e97 100644 GIT binary patch delta 398 zcmYLF!AiqG5Zy^OX_BT%)K)=^-h?9JT?9b{@e&m2B_2x3ZfPNH$}U9@f(QM9u;3qg z@(*(I7yJQnCJ5by$J@6v@6GO~^VNx}UN2y{et!GY7pS8HxT{YtcW;>Rg#XTjFZr9D zJ0f^s!*0F$25#=*w7-unlI0*+ZjG3L+?L#Yz+>#;h2{tWOF%`YfE3Qnp|$s#I}(e8 zeZhp4yDjG}???}Ihd73~4IgQ#RE!>37N-^!@dG9Nir6MUWR#E; p04sv4=3y)XiTG)7!QL0lK_hdGXTA49H;;Q diff --git a/internal/database.py b/internal/database.py index 81983df..298451e 100644 --- a/internal/database.py +++ b/internal/database.py @@ -4,7 +4,7 @@ DB_CONFIG = { "host": "111.229.38.129", "user": "root", "password": "zl981023", - "database": "blogapi", + "database": "test", "charset": "utf8mb4", "cursorclass": pymysql.cursors.DictCursor, } diff --git a/internal/models.py b/internal/models.py new file mode 100644 index 0000000..fb7de62 --- /dev/null +++ b/internal/models.py @@ -0,0 +1,19 @@ +from pydantic import BaseModel + +# Token相关的模型 +class Token(BaseModel): + access_token: str + token_type: str + +class TokenData(BaseModel): + username: str = None + +# User相关的模型 +class User(BaseModel): + username: str + email: str = None + full_name: str = None + disabled: bool = None + +class UserInDB(User): + hashed_password: str diff --git a/internal/schemas.py b/internal/schemas.py deleted file mode 100644 index 5804c64..0000000 --- a/internal/schemas.py +++ /dev/null @@ -1,11 +0,0 @@ -from pydantic import BaseModel - -class Token(BaseModel): - access_token: str - token_type: str - -class TokenData(BaseModel): - username: str | None=None - -class User(BaseModel): - username: str \ No newline at end of file diff --git a/main.py b/main.py index e1a51fa..344049e 100644 --- a/main.py +++ b/main.py @@ -1,15 +1,16 @@ -from fastapi import FastAPI,HTTPException +from datetime import timedelta +from fastapi.security import OAuth2PasswordRequestForm +from fastapi import Depends, FastAPI, HTTPException, status from dependencies import * -from internal.schemas import * -# 初始化 FastAPI 应用 -app = FastAPI() +from internal.models import Token +app=FastAPI() -# 数据库连接参数 - -# 定义登录接口 +# 用户登录 @app.post("/token", response_model=Token) -async def login_for_access_token(username: str, password: str): - user = authenticate_user(username,password) +async def login_for_access_token( + form_data: OAuth2PasswordRequestForm = Depends(), +) -> Token: + user = authenticate_user(form_data.username, form_data.password) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, @@ -20,5 +21,29 @@ async def login_for_access_token(username: str, password: str): access_token = create_access_token( data={"sub": user.username}, expires_delta=access_token_expires ) - return Token(access_token=access_token, token_type="bearer") + return {"access_token": access_token, "token_type": "bearer"} + +# 注册新用户 +@app.post("/register/", response_model=UserInDB) +async def register_user(user: UserInDB): + # 检查用户名是否已经存在 + existing_user = get_user(user.username) + if existing_user: + raise HTTPException(status_code=400, detail="Username already registered") + + # 创建新用户并保存到数据库 + hashed_password = get_password_hash(user.hashed_password) + insert_query = "INSERT INTO users (username, email, full_name, hashed_password) VALUES (%s, %s, %s, %s)" + user_data = (user.username, user.email, user.full_name, hashed_password) + execute_query(insert_query, user_data) + + # 返回创建的用户信息 + return user + +@app.get("/users/me/", response_model=User) +async def read_users_me(current_user: User = Depends(get_current_active_user)): + return current_user +@app.get("/users/me/items/") +async def read_own_items(current_user: User = Depends(get_current_active_user)): + return [{"item_id": "Foo", "owner": current_user.username}]