fastapi 构建一个登陆界面,并按照用户角色跳转不同页面,并用session记录管理账号登陆状态
时间: 2024-09-11 10:03:29 浏览: 112
FastAPI是一个现代、快速(高性能)的Web框架,用于构建APIs,使用Python 3.6+类型提示。要使用FastAPI构建一个登录界面,并根据用户角色跳转到不同的页面,并且使用session记录管理账号登录状态,可以按照以下步骤进行:
1. 安装必要的库:
```
pip install fastapi uvicorn python-multipart
pip install "uvicorn[standard]"
```
2. 创建FastAPI应用程序并定义用户模型和登录接口:
```python
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from typing import Optional
from pydantic import BaseModel
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from fastapi.responses import RedirectResponse, HTMLResponse
app = FastAPI()
# 假设我们有一个简单的用户模型
class User(BaseModel):
username: str
password: str
# 假设的用户数据库
users_db = {
"admin": "adminpass",
"user": "userpass"
}
# 创建一个OAuth2密码承载器实例
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# 登录路由
@app.post("/token")
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
user = authenticate_user(users_db, form_data.username, form_data.password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
access_token = create_access_token(
data={"sub": user.username}
)
return {"access_token": access_token, "token_type": "bearer"}
def authenticate_user(fake_db, username: str, password: str):
if username in fake_db and fake_db[username] == password:
return True
return False
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=15)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
# 这里应该添加session管理的逻辑,例如使用requests.Session()来记录用户的状态
```
3. 创建一个中间件来管理session:
```python
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.types import Message
from starlette.responses import Response
class SessionMiddleware(BaseHTTPMiddleware):
async def set_session(self, request: Request, response: Response, session_id: str):
if not hasattr(request.state, 'session'):
request.state.session = {}
request.state.session['id'] = session_id
response.set_cookie(key='session', value=session_id)
async def set_default_session(self, request: Request, response: Response):
session_id = request.cookies.get('session')
if not session_id:
session_id = secrets.token_hex(16)
await self.set_session(request, response, session_id)
async def dispatch(self, request, call_next):
response = await call_next(request)
session_id = request.cookies.get('session')
if session_id:
await self.set_session(request, response, session_id)
return response
app.add_middleware(SessionMiddleware)
```
4. 使用路由来处理不同的角色,并根据角色跳转到不同的页面:
```python
@app.get("/")
async def home(request: Request):
await request.state.session.set_default_session(request)
return RedirectResponse(url="/home")
@app.get("/home")
async def home(request: Request):
user = request.state.session.get('id', None)
if user is None:
return RedirectResponse(url="/login")
return HTMLResponse(f"<h1>Welcome to your dashboard {user}!</h1>")
@app.get("/login")
async def login(request: Request):
return HTMLResponse("<form action='/token' method='post'>Username: <input type='text' name='username'><br> Password: <input type='password' name='password'><br><input type='submit' value='Login'></form>")
@app.get("/admin")
async def admin_panel(request: Request):
await request.state.session.set_default_session(request)
user = request.state.session.get('id', None)
if user != "admin":
return RedirectResponse(url="/login")
return HTMLResponse("<h1>Admin Panel</h1>")
```
5. 启动FastAPI应用程序:
```python
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
```
请注意,以上代码是一个简化的示例,不包含所有的错误处理和安全措施。在实际部署时,您需要考虑使用HTTPS、密码加密存储、令牌刷新机制、跨站请求伪造(CSRF)保护等安全实践。此外,应该使用环境变量来管理密钥和敏感配置,而不是直接在代码中硬编码。
阅读全文