From a38dc6b093b2292418d216d56381650af18357fd Mon Sep 17 00:00:00 2001
From: SunFree <17315650350@163.com>
Date: Mon, 8 Apr 2024 14:06:24 +0800
Subject: [PATCH] add all

---
 __init__.py                                   |   0
 __pycache__/dependencies.cpython-310.pyc      | Bin 0 -> 2106 bytes
 __pycache__/main.cpython-310.pyc              | Bin 0 -> 876 bytes
 dependencies.py                               |  74 ++++++++++++++++++
 internal/__init__.py                          |   0
 internal/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 125 bytes
 internal/__pycache__/database.cpython-310.pyc | Bin 0 -> 784 bytes
 internal/__pycache__/schemas.cpython-310.pyc  | Bin 0 -> 709 bytes
 internal/database.py                          |  27 +++++++
 internal/schemas.py                           |  11 +++
 main.py                                       |  24 ++++++
 routers/__init__.py                           |   0
 12 files changed, 136 insertions(+)
 create mode 100644 __init__.py
 create mode 100644 __pycache__/dependencies.cpython-310.pyc
 create mode 100644 __pycache__/main.cpython-310.pyc
 create mode 100644 dependencies.py
 create mode 100644 internal/__init__.py
 create mode 100644 internal/__pycache__/__init__.cpython-310.pyc
 create mode 100644 internal/__pycache__/database.cpython-310.pyc
 create mode 100644 internal/__pycache__/schemas.cpython-310.pyc
 create mode 100644 internal/database.py
 create mode 100644 internal/schemas.py
 create mode 100644 main.py
 create mode 100644 routers/__init__.py

diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/__pycache__/dependencies.cpython-310.pyc b/__pycache__/dependencies.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..629083140a39a46619874a3c3b69c339dbec6031
GIT binary patch
literal 2106
zcmZWqOK;mo5Z+x<67{m>cU~=o0%@uM4IDdm?4m8=Dr}u5Q36YW+eH9^=B{kIe5lJ+
z92+#y*16_C*vI^ZUi&Y2?J3tD3-mEVIgXQ1*vAZJcW1tt`4rdd6#`$Y)#(3KCge{P
z&VL0E?!ZWXhe;4Y0}>KWLdq#cnFTB~xDlG%3=6!F>x`fnmUt<&xRuLhP!21+lJ5&a
zHLUSkSm$+0WJMIWsVE8SCF5hF%*REAH$;_Bh?=OsAbe7ciE&t`L_<!C2|3+2#iW>e
zVe%PqMa;-qF)JzP=EQ{;1wJQDSwEtEDlUR06PLtg&|VPJUDEpKHTX|jEVG2GrS?Oa
zm2nm_&~D4f>g&DUWBa)$2ilLLtaMinWF(TTm}plI6Fm6+X3thCR++K8r&~0uwblMW
zx8q35=Nb&^^11YeS~@=urP|LXJSE{N$BUy#dUz`@Zh3elGu@$%Ta1?yZ%2kQ$tpq)
zl=Q${@H_LXVqr<nuiomr?y~1DEG;d2D>qkeE-!E0c2}2{7q?ay`?u#;SNqHT`Ti{r
zt@@x{S&=JZQQqc-_3pyb^6QTwV2@$gryuT37;P9y4JJ*FX-ZOh!n))Y?LZ9G!Ja^m
zF{G^cOe(*>4~~uv0@sh6ftw_Iu@ZcI$4z#mI8(eLY7*}I`?CGT)2$%hcHDvg6k-Ah
zW#suXxiQ$!#z)tk9hycr(5D(zxc4YbZ$8``Fmhk9L`S}!&@NHqAhwulz>=Bh2_(aM
z<6G{?XqrNUiEXLRo^;Uq0;uzMD^$&)i8V~5iri4DSrFfW49ow_jRg<{J!G1sEG2z<
z#14(rNNR#~NoojoksO+urZhE=STZ-#Lg^WugKJ&;f!*#kuQ$Klc=WJ|?<LL6b$i3k
z_xN`6tLD`tcK|}efOAY*1%>YB`mB%_7BAy*2g=yx<B5*dxjcLjJQUiFjI@uX<>0w1
za9e`NnY2bt_*t})uj&#gJDG|1Vkr-NB@-uaj}H(*RPw}hV3U$#azYMSN>yFcV|D@s
zHAfDOs63Lip-n+w=DL&}7X(WUpPm4H=;CfEW!lnZVZ1aB&C~?6%noF;6#5Z#Qj!_q
z2*_nO*p8L2cfwXBGrf4Qudr~k;!t~0yr(cl+2yr%+wOLq-lO|=$FYBSd~d^c9^UIb
z>DgVd9AM)sD?bKB84H<Jx^{cR?m74EAG7k>gYO<~-0Q7B1k5jkRSp#|>)07t^Wq2;
zULDE80UCH8@Tt?LcRf!giKFA6WONNKOU7Wb0O&C~$;M~{b_(@bAvbxa^buWj^A8wF
z1k<ln6HRxSpn?g&PMCleJ($(Tu9*^D&`6>M&@sTbB#I{#>r#**QO%V8MmI@RHi@?O
zuTz3Q)a?;nPK_gqsOOeTsLeA_>KuIBj)#G0MzL-_a|0idYeHnu%-VN@<e;&+x%v6p
zx!TH#-$++U1x#8UF($AGAY2quyMB<BcBCty=v$Om&T<LqO@>>oib7ISMVPV~q+#dQ
z{7vUcXYEOE9Wui0yQf(b67N)3(fU)gHlVjv2}LYk$lGVI@R@U-I`S>058VAAc17M$
znTgHte)by372Z%Oh%@gN?DzzqV!tqEQbvok_zx>ivI_JKbkBb^W-|7#RmdenErRKY
zo-XDEIx5Uk-vvydq4GE}y?L<Q+>ODB+<(kBA4d)g{H+_O1gzi>neYi8*cj+3xPh&?
z<-(Di9;$c`cJf<5)F&t+myU?dNVLkKfwuNNombq*M`Y{wqqn{cV=)Zm*T}sI5=Dbd
Yvj*@)gN+%cVM45yVVRTWboEm8f2t${%>V!Z

literal 0
HcmV?d00001

diff --git a/__pycache__/main.cpython-310.pyc b/__pycache__/main.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..afa68d08b997a7d561e8a508d4f2bb3bb4668ae6
GIT binary patch
literal 876
zcmY*XTWeE65I(!-nwUy#tB8X1(Fj%rpG3r1k2GG=(wtIRgk^hnVo#fMVRwUVNkOfz
z`62!e|HXOr$-f|o&L%Cyftlgk%gi^Ia%rjQpd8(84|}fT{Ip<Ed<4%?^=mZJk!0lL
zgpr&wN-U-$H<^1cae$mV%m@E4kS>JMn^NgRBm;<so(yI5%{wQoAsYjy)BJ_;oDQwS
zS3;ZacCTLAOp@*RIEBh&Wziuuxpx{oFy#>-U{@9Bsw_0{yp%Aiqp=26h#cyu5?X&M
zl}xD(c_Eg!)gP$(Et)UHI1^_=&gmJQP`zx3p@*&{l1eut$kqKyjAwl5Psy2U0vSx`
zVVIGLE5j*0^Gr1HWF#9?YT5Ts@AQhaR0>kFc1dNeRBM-HPTPBXd-uCza{z_OQel7v
zFF+_z9k;%sjWA=)Q!IrA5{$@3b$9?mg3?%dm}kY<fUaFV-p3w!QW(LO;JC`L4IJx7
z80^o((Yhtl6tw2EUe(Q+<L0D-PJ>+&3lz9zs&LFs9n2}P>$dCs@xw=ax8L1OHn(<q
zEPh!xOqRnu&+YEUMm!ksWa~}b=kfdP-cHQl_4>O>JYXxS0<4WMGElbfwV%u;=g*J|
z?2%{Fv(?47{Guk+!Ux|SwT$lfO8n%*{;2%OMU{QXMOLg=C-n_H$O=9z)qlzC_Uc<`
z=;tQ&2qjhn68vfUlr%~3x8<r;yzY0JEF9vhVN7KgW!47Pl2Ab*p-3~(teq9cZq;aA
zrw5P=9Dt}Q=2fLOs*Rs;AV$sN&6qBj6?+>!#pN82;2A-rZAon>A`uB_%fCtf0St5T
Aga7~l

literal 0
HcmV?d00001

diff --git a/dependencies.py b/dependencies.py
new file mode 100644
index 0000000..b798ddd
--- /dev/null
+++ b/dependencies.py
@@ -0,0 +1,74 @@
+from datetime import datetime, timedelta
+
+from fastapi import HTTPException, Depends, status
+from jose import JWTError, jwt
+from passlib.context import CryptContext
+
+from internal.database import execute_query, create_connection
+
+# 设置密码上下文
+pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
+
+# 随机秘钥
+SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7" 
+# JWT签名算法变量
+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
+
+# 创建访问令牌
+def create_access_token(data: dict, expires_delta: timedelta = None):
+    to_encode = data.copy()
+    if expires_delta:
+        expire = datetime.utcnow() + expires_delta
+    else:
+        expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
+    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 用于处理认证失败的情况
+    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
+    except JWTError:
+        # 如果 JWT 解码失败,则返回认证异常
+        raise credentials_exception
+    
+    # 根据用户名从数据库中获取用户数据
+    user = authenticate_user(username)
+    if user is None:
+        raise credentials_exception
+    
+    # 返回获取到的用户数据
+    return user
diff --git a/internal/__init__.py b/internal/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/internal/__pycache__/__init__.cpython-310.pyc b/internal/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1522cfa845643537682ec6c4e5ebf91f1a0bb404
GIT binary patch
literal 125
zcmd1j<>g`kf+xZPX(0MBh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2D3)hZ?_CqF$t
uu^=-hGp{7IC@(Q5CO$qhFS8^*Uaz3?7Kcr4eoARhsvSsYF%ytrVE_QVpBT3Q

literal 0
HcmV?d00001

diff --git a/internal/__pycache__/database.cpython-310.pyc b/internal/__pycache__/database.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bc94863883f15e02d1d7e527c4ef78594f368993
GIT binary patch
literal 784
zcmYjP&ubJh6i#L`nRI`#1uF<11VPx#;%<9rMMP|^cv%k~#IUf;PO^5(%w(Hns9Uxm
zv}gSXM7rR`e<@c_p1swJFS9M(7v7imk~ewZdv8>;SwkRypR^}G0)&2hXI)}&UV@q(
z0D%O~5Jw^qp&%j>RH9>i9EkWk<)L6=;}UTqnxZZmmzYNazek<cANUdt&RV@*uiNkM
zb+>oBz5bpfS}DufS+=*^d)nXT@i<eTlG&8UrJd~N<DCw5<VYFoNNJ>YY?c^vs<hxt
zBsLi*M!GmXO0<!d*V9rPrPB;zQlD>K2srzorVU_$vA|PggP-`T=NAlqp-$-H**u?{
zlMLQeMIlq`HV$5m_TLQ--@ehl3wLn+==HOqXFCGA!)alqE|P3`%c?t@yUkR~#LCgl
zTT@juJpt%2YGd7i?Jx}iZ-s)vKr5O842v$%dAJC#@DhD{a84HFDp;TeUIrK~0=)%(
zxJ2hs;ctkyKEQYgtcwt%g7uJje2Ovh>mw+<6fIXft@a2?$AeB>k#Tg@KOW1^GA*ri
zY$7c*H_Q0SQiX&dmFH9IqBK)R!g!*SQtG**vqUGk(JkQZh%Z_DY8}<ml$pJ2oUZ%h
z=1q=K_4Otknfm|~*Kh+9Ko$gF9{yvLfv30N3TAZJq1rcy$1A3W*AAws-LJ;3{Xbk4
kQiZQ2tOi$QWzTaZ%1pk%5NqxMFcgFVUM-60HLJDAe<>Wc@c;k-

literal 0
HcmV?d00001

diff --git a/internal/__pycache__/schemas.cpython-310.pyc b/internal/__pycache__/schemas.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..592a5dc1f5934afb4fdcd689c5cede3f8f5eeea5
GIT binary patch
literal 709
zcma)3yH3L}6t&}|O+rdDRE#iZ;R8^GstUwJ7w8gIvP^6sA}``}=nUdt`Zvs8nfL`J
z?sZXBi6UXi=lWbf?m52oU=R`*Z%KUr4)FuY?r?!jU}^+OBrQluQ%cDdk&a}qL^4HR
zSn2?Gr3c)zoB{92KJdQfuJmt65`4ldB%vml3azedsfr9UyMqClz|_Y8ilkJM)R_~-
zlq>0Y6P+>Ch4)<J-PTX4GLgtKr8Vy?3vJ-ts!_AGXMD~pQ7X<&$az`IWr6F6^XH`~
zes-AdS~KKaR8`%HF0U)i`I@v5h_LW=a(TA6E9wU>ntYL0ooXvlEOhp$N}*4iRg1!L
z>K;Hyd>T=k`>#VuQ|oa`lqb<41&7Q8*5QTd#LW0hjb%%f^x8fu^AQ4sAp-WYJwVv%
z-mC_gI|RU68k-uD5w)4W<sHGX-wlwCmF3Psimf_p(eU1iu`RT%2p@u(Spq$2R#H@5
hp0y5M#(%SF?16o68GpQK-8qG`8jVLJc4BwLz5#Oug#!Qp

literal 0
HcmV?d00001

diff --git a/internal/database.py b/internal/database.py
new file mode 100644
index 0000000..81983df
--- /dev/null
+++ b/internal/database.py
@@ -0,0 +1,27 @@
+import pymysql
+
+DB_CONFIG = {
+    "host": "111.229.38.129",
+    "user": "root",
+    "password": "zl981023",
+    "database": "blogapi",
+    "charset": "utf8mb4",
+    "cursorclass": pymysql.cursors.DictCursor,
+}
+
+# 创建数据库连接
+def create_connection():
+    return pymysql.connect(**DB_CONFIG)
+
+# 执行 SQL 查询
+def execute_query(query, params=None, fetchall=False):
+    conn = create_connection()
+    with conn.cursor() as cursor:
+        cursor.execute(query, params)
+        if fetchall:
+            result = cursor.fetchall()
+        else:
+            result = cursor.fetchone()
+    conn.commit()
+    conn.close()
+    return result
\ No newline at end of file
diff --git a/internal/schemas.py b/internal/schemas.py
new file mode 100644
index 0000000..5804c64
--- /dev/null
+++ b/internal/schemas.py
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 0000000..e1a51fa
--- /dev/null
+++ b/main.py
@@ -0,0 +1,24 @@
+from fastapi import FastAPI,HTTPException
+from dependencies import *
+from internal.schemas import *
+# 初始化 FastAPI 应用
+app = FastAPI()
+
+# 数据库连接参数
+
+# 定义登录接口
+@app.post("/token", response_model=Token)
+async def login_for_access_token(username: str, password: str):
+    user = authenticate_user(username,password)
+    if not user:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail="Incorrect username or password",
+            headers={"WWW-Authenticate": "Bearer"},
+        )
+    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
+    access_token = create_access_token(
+        data={"sub": user.username}, expires_delta=access_token_expires
+    )
+    return Token(access_token=access_token, token_type="bearer")
+
diff --git a/routers/__init__.py b/routers/__init__.py
new file mode 100644
index 0000000..e69de29