写一个fastapi的jwt登录认证
时间: 2023-09-16 15:05:51 浏览: 307
FastAPI-Auth:使用FastAPI和JWT的示例应用
### 回答1:
我可以给你一些提示来帮助你实现fastapi的jwt登录认证。首先,你需要安装fastapi和pyjwt库。然后,构建一个JWT认证函数,并将它添加到登录路由上。接下来,创建一个签名密钥,并将其添加到认证函数中。最后,将签名密钥添加到环境变量中,以便可以在登录路由中使用。
### 回答2:
FastAPI是一个基于Python的现代,高性能的Web框架,它提供了快速构建API和Web应用程序的能力。JWT(JSON Web Token)是一种用于在网络应用间传递声明的安全的、基于JSON的令牌。
要实现FastAPI的JWT登录认证,需要使用以下步骤:
1. 导入所需的库:
```python
from fastapi import FastAPI
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from passlib.context import CryptContext
from jose import JWTError, jwt
from datetime import datetime, timedelta
```
2. 配置密码哈希和jwt密钥:
```python
SECRET_KEY = "your_secret_key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/login")
```
3. 创建用户模型和密码校验函数:
```python
class User(BaseModel):
username: str
password: str
def verify_password(plain_password, hashed_password):
return pwd_context.verify(plain_password, hashed_password)
```
4. 创建用户认证函数和生成JWT的函数:
```python
async def authenticate_user(username: str, password: str):
user = get_user_from_db(username)
if not user:
return False
if not verify_password(password, user.password):
return False
return user
def create_access_token(data: dict, expires_delta: timedelta):
to_encode = data.copy()
expire = datetime.utcnow() + expires_delta
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
```
5. 创建登录路由和保护需要认证的路由:
```python
app = FastAPI()
@app.post("/login")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
user = await authenticate_user(form_data.username, form_data.password)
if not user:
return {"error": "Invalid username or password"}
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={"sub": user.username}, expires_delta=access_token_expires
)
return {"access_token": access_token, "token_type": "bearer"}
@app.get("/protected")
async def protected_route(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise credentials_exception
except JWTError:
raise credentials_exception
user = get_user_from_db(username)
if user is None:
raise credentials_exception
return {"user": user}
```
以上代码示例了一个快速实现的FastAPI JWT登录认证。在登录路由中,用户提供用户名和密码,然后校验用户名和密码是否正确,如果正确则生成一个JWT,并返回给用户。在保护的路由中,用户需要提供JWT作为认证凭证,服务器会验证JWT的有效性,并根据JWT中的信息返回相应的内容。
### 回答3:
FastAPI是一个Python的Web框架,它提供了快速构建API的能力。JWT(JSON Web Token)是一种用于身份验证和授权的开放标准。下面是一个使用FastAPI实现JWT登录认证的示例。
首先,需要安装FastAPI和PyJWT等必要的库。可以使用pip命令进行安装。
```shell
pip install fastapi
pip install python-jose[cryptography]
```
接下来,创建一个Python文件,例如`main.py`,并使用以下代码编写JWT登录认证的示例。
```python
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import jwt, JWTError
from datetime import datetime, timedelta
from passlib.context import CryptContext
app = FastAPI()
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
fake_users_db = {
'username': {
'username': 'username',
'password': '$2b$12$Jl7haqJbg.fBx5AZvK7Hj.57A6FYRXTFmL/NyU.JvMhLDwwBUUz/e' # hashed_password: password
}
}
pwd_context = CryptContext(schemes=['bcrypt'], deprecated='auto')
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
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):
if username in fake_users_db:
user_dict = fake_users_db[username]
return user_dict
def authenticate_user(username: str, password: str):
user = get_user(username)
if not user:
return False
if not verify_password(password, user['password']):
return False
return user
def create_access_token(data: dict, expires_delta: timedelta):
to_encode = data.copy()
expire = datetime.utcnow() + expires_delta
to_encode.update({'exp': expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
user = authenticate_user(form_data.username, form_data.password)
if not user:
raise HTTPException(status_code=401, detail="Incorrect username or password")
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(data={"sub": user["username"]}, expires_delta=access_token_expires)
return {"access_token": access_token, "token_type": "bearer"}
@app.get("/me")
async def read_users_me(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise HTTPException(status_code=401, detail="Invalid authentication credentials")
except JWTError:
raise HTTPException(status_code=401, detail="Invalid authentication credentials")
user = get_user(username=username)
if user is None:
raise HTTPException(status_code=404, detail="User not found")
return user
```
上面的代码中,首先定义了一个用于存储用户信息的`fake_users_db`字典。然后使用`CryptContext`来进行密码的哈希操作。`verify_password`用于验证密码是否匹配,`get_password_hash`用于生成密码的哈希值。`get_user`用于返回指定用户名的用户信息。`authenticate_user`用于验证用户名和密码,并返回用户信息。`create_access_token`用于生成JWT令牌。
接下来,使用`@app.post`装饰器定义了一个`/token`的登录路由,接收用户名和密码,验证后生成并返回JWT令牌。
最后,使用`@app.get`装饰器定义了一个`/me`的路由,该路由需要进行JWT登录认证。在函数中解码JWT令牌,获取到用户信息并返回。
通过上述代码示例,我们实现了一个使用FastAPI实现JWT登录认证的API。可以使用`uvicorn`命令运行该API。
```shell
uvicorn main:app
```
接下来,可以通过向`http://localhost:8000/token`发起POST请求进行登录认证,获取到JWT令牌。然后使用该令牌向`http://localhost:8000/me`发起GET请求获取当前用户信息。
阅读全文