회원가입
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
Tags:
클라우드