로그인 추가하기
2025. 4. 13. 17:17ㆍ파이썬/FastAPI
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from datetime import datetime, timedelta
from typing import Optional
import uuid, hashlib, base64, hmac, requests
app = FastAPI()
# Secret for user JWT token
JWT_SECRET = "your-jwt-secret-key"
JWT_ALGORITHM = "HS256"
JWT_EXPIRE_MINUTES = 60
# Dummy user
fake_user = {
"username": "abc",
"password": "ert" # Plaintext for simplicity (use hashed passwords in prod!)
}
# OAuth2 scheme
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")
SERVER_URL = "https://test.com"
# === Auth ===
def create_access_token(data: dict, expires_delta: timedelta):
to_encode = data.copy()
expire = datetime.utcnow() + expires_delta
to_encode.update({"exp": expire})
return jwt.encode(to_encode, JWT_SECRET, algorithm=JWT_ALGORITHM)
def verify_token(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
username = payload.get("sub")
if username != fake_user["username"]:
raise HTTPException(status_code=401, detail="Invalid user")
return username
except JWTError:
raise HTTPException(status_code=401, detail="Invalid token")
@app.post("/login")
def login(form_data: OAuth2PasswordRequestForm = Depends()):
if form_data.username != fake_user["username"] or form_data.password != fake_user["password"]:
raise HTTPException(status_code=400, detail="Incorrect username or password")
access_token = create_access_token(
data={"sub": fake_user["username"]},
expires_delta=timedelta(minutes=JWT_EXPIRE_MINUTES)
)
return {"access_token": access_token, "token_type": "bearer"}
# === Upbit Request Helper ===
def generate_jwt(query_string: str) -> str:
query_hash = hashlib.sha512(query_string.encode()).hexdigest()
header = {"alg": "HS256", "typ": "JWT"}
payload = {
"access_key": ACCESS_KEY,
"nonce": str(uuid.uuid4()),
"query_hash": query_hash,
"query_hash_alg": "SHA512"
}
def b64url(d):
return base64.urlsafe_b64encode(str(d).replace("'", '"').encode()).decode().rstrip("=")
h_b64 = b64url(header)
p_b64 = b64url(payload)
sig = hmac.new(SECRET_KEY.encode(), f"{h_b64}.{p_b64}".encode(), hashlib.sha256).digest()
s_b64 = base64.urlsafe_b64encode(sig).decode().rstrip("=")
return f"{h_b64}.{p_b64}.{s_b64}"
# === Protected Route ===
@app.get("/test")
def get(
state: str = "done",
page: int = 1,
user: str = Depends(verify_token)
):
params = {
"state": state,
"page": page,
}
query_string = "&".join(f"{k}={v}" for k, v in params.items())
jwt_token = generate_jwt(query_string)
headers = {
"Authorization": f"Bearer {jwt_token}"
}
response = requests.get(f"{SERVER_URL}/v1/orders", headers=headers, params=params)
if response.ok:
return response.json()
else:
return {"error": response.status_code, "message": response.text}
Token 얻기
curl -X POST http://localhost:8000/login \
-d "username=abc&password=ert" \
-H "Content-Type: application/x-www-form-urlencoded"
/test 호출
curl http://localhost:8000/test \
-H "Authorization: Bearer <your_token_here>"
'파이썬 > FastAPI' 카테고리의 다른 글
주요 파일 별도 저장하기 (0) | 2025.04.13 |
---|---|
FastAPI 이미지 만들기 (1) | 2024.09.16 |
파일 다운로드 설정 (0) | 2024.06.28 |
FastAPI CORS 설정 (0) | 2024.04.01 |
FastAPI post 설정 (1) | 2024.03.16 |