FAST API 로그인 세션

회원가입

brcypt방법으로 비번을 해싱한다. 

아래 user_db를  키(아이디)-값(해싱값) 쌍으로 db에 저장한다. 

{'alpaco1': '$2b$12$8kEMc4lczjjqhwHg8DTQ/uVUWJTxqp2QJUWFqDZLTUrttEXowIyWO'}

# 유저를 담을 그릇
user_db = {}

# 아이디랑 비밀번호 입력
uid = "alpaco1"
pwd = "qwer1234"

# 유저 비밀번호 암호화
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated = "auto")
hashed_password = pwd_context.hash(pwd)

# user_db에 입력 uid : 해싱된 password
user_db[uid] = hashed_password

print(user_db)


로그인

1. 아이디 및 비밀번호 체크

TrueOrFalse = pwd_context.verify(pwd, user_db[uid])

2. 세션 값을 다음과 같은 형태로 만든다. 

to_encode = {'sub': uid, 'exp': 이용권기한날짜}

3. 세션 토큰을 만든다. (시크릿 키를 포함한다.)

SECRET_KEY = secrets.token_hex(32)

result = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

전체 과정

# 아이디랑 비밀번호 입력
uid = "alpaco1"
pwd = "qwer1234"

#로그인 검증 시작

#유저 입력 vs 유저정보딕셔너리에서 비밀번호 비교
TrueOrFalse = pwd_context.verify(pwd, user_db[uid])

#비밀번호가 맞다면~ 입장권을 줘야한다.
from datetime import datetime, timedelta
import jwt
import secrets

duration = 30
이용권기한날짜 = datetime.utcnow() + timedelta(minutes=duration)
SECRET_KEY = secrets.token_hex(32)

# JWT 인자에 맞게 딕셔너리 만듦
to_encode = {'sub': uid, 'exp': 이용권기한날짜}

ALGORITHM = "HS256" #토큰 암호 알고리즘

# 세션 토큰 생성
result = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
print(result)


실제 구현 예제

세션 값을 만든다. data={"sub": username}를 받아서, 인증 만료기간을 넣는다.

세션 토큰 형태로 리턴한다. (to_encode, SECRET_KEY)

# JWT 토큰 생성 함수
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, SECRET_KEY, algorithm=ALGORITHM)

1. 아이디 및 비밀번호 체크

2. 세션 토큰을 만든다.

3. 페이지 이동 인스턴스 생성 및 인스턴스에 토큰을 건다. (response.set_cookie)

# 로그인
@app.post("/login")
async def login(username: str = Form(...), password: str = Form(...)):
    user = fake_users_db.get(username)
   
    if not user or not verify_password(password, user["password"]):
        raise HTTPException(status_code=401, detail="아이디 또는 비밀번호가 잘못되었습니다.")
   
    access_token = create_access_token(
        data={"sub": username},
        expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    )
   
    response = RedirectResponse(url="/dashboard", status_code=303)

    # HTTP-only 쿠키에 토큰 저장
    response.set_cookie(
        key="access_token",
        value=access_token,
        httponly=True,  # JavaScript에서 접근 불가
        secure=False,    
        samesite="lax", # CSRF 보호
        max_age=1800    # 30분
    )
    print("access_token:",access_token)  
    return response




댓글 쓰기

다음 이전