오늘은 로그인, 유저 조회를 구현해볼거다
로그인
생각 보다 진도가 너무 안나가서 ... 불안해진다.. ㅠㅠ
일단 단순히 DB에 있는 정보랑 비교해서 맞게 입력했다면 로그인 성공 여부를 구현해 보자
pydantic 을 이용해 로그인 정보를 벨리데이션 해준다.
schemas.py
class UserLogin(BaseModel):
email: str
password: str
로그인 절차는
1. email, password 를 받아오고
2. db에서 email를 찾는다
3. 없다면 오류를 보내고 있다면 비밀번호를 비교해준다
4. 비번도 맞으면 로그인 성공
main.py
# 위쪽에 get_user, verify_password 를 추가
from BE.crud import create_user, get_user, verify_password
@app.post("/login")
def login(user_login: UserLogin, db: Session = Depends(get_db)):
user_in_db = get_user(db, user_login.email)
if not user_in_db:
raise HTTPException(status_code=400, detail="이메일 또는 비밀번호를 잘못 입력했습니다.")
if not verify_password(user_in_db.password, user_login.password):
raise HTTPException(status_code=400, detail="이메일 또는 비밀번호를 잘못 입력했습니다.")
return {"message":"로그인 되었습니다."}
crud.py
def get_user(db: Session, email: str):
return db.query(User).filter(User.email == email).first()
def verify_password(hashed_password, plain_password):
return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password.encode('utf-8'))
를 추가한다.
서버를 실행 하고 테스트 해보면
된다!!
이제 로그인 했을때 jwt로 access_token을 발급해보자
.env
ALGORITHM=
JWT_ACCESS_TOKEN_SECRET=
JWT_ACCESS_TOKEN_EXPIRRED_TIME=
를 추가해서 적당히 적는다
알고리즘은 HS256 를 사용 할거니 알고리즘에 적는다.
jwt를 사용 하기 위해
pip install python-jose
를 설치한다.
main.py
import os
from jose import jwt
from datetime import timedelta, datetime
from dotenv import load_dotenv
를 추가해서 jwt, dotenv 를 가져온다.
아래쪽에
load_dotenv('.env')
ALGORITHM = os.environ["ALGORITHM"]
JWT_ACCESS_TOKEN_SECRET = os.environ["JWT_ACCESS_TOKEN_SECRET"]
JWT_ACCESS_TOKEN_EXPIRRED_TIME = int(os.environ["JWT_ACCESS_TOKEN_EXPIRRED_TIME"])
를 추가해서 .env 정보를 불러온다.
JWT_ACCESS_TOKEN_EXPIRRED_TIME 은 숫자형으로 바꿔주기 위해 int() 를 사용해주고
엑세스 토큰을 만들어줄 함수를 만들어준다.
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes= JWT_ACCESS_TOKEN_EXPIRRED_TIME)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode( to_encode, JWT_ACCESS_TOKEN_SECRET, algorithm=ALGORITHM )
return encoded_jwt
이전에 만들었던 로그인 api 에 아래 부분을 추가해준다..
access_token_expires_minutes = timedelta(minutes= JWT_ACCESS_TOKEN_EXPIRRED_TIME)
access_token_payload ={
'sub':user_in_db.email,
'exp':datetime.utcnow() + access_token_expires_minutes,
'iat':datetime.utcnow()
}
access_token = create_access_token(access_token_payload)
return {"access_token": access_token}
서버를 실행하고 작동을 확인해본다.
유저 조회
간단하다.. ㅋㅋㅋㅋ
main.py
# 상단에는 get_user_info를 추가
from BE.crud import create_user, get_user, verify_password, get_user_info
@app.get("/users/{userId}")
def user_info(userId, db: Session = Depends(get_db)):
user_info_db = get_user_info(db, userId)
return user_info_db
crud.py
def get_user_info(db: Session, userId: int):
user_info_db = db.query(User).filter(User.id == userId).first()
return user_info_db
라고 생각한게 잘못이였다 ㅋㅋ 정보를 다 불러와서 필요한 정보만 가져올 필요가 있다.. ㅎㅎ
with_entities()를 사용하면 된다고 나와서
db.query(User).filter(User.id == userId).with_entities(User.nickname, User.image).first()
으로 수정 후 조회 했는데.. ?
네??
닉네임이랑 이메일을 뽑아서 보내주자.. ㅎㅎ
crud.py
def get_user_info(db: Session, userId: int):
user_info_db = db.query(User).filter(User.id == userId).with_entities(User.nickname, User.image).first()
nickname, image = user_info_db
return {"nickname": nickname, "image": image}
하면 간단하게 아래처럼 정보를 불러올수있다.
여기서.. 없는 데이터를 조회했을때 문제가 발생한다..
500 와 오류 로그가 뿜뿜 해버린다 조회한 내용이 없을땐 None을 보내주자
crud.py
if user_info_db is None:
return None
부분을 추가해서
def get_user_info(db: Session, userId: int):
user_info_db = db.query(User).filter(User.id == userId).with_entities(User.nickname, User.image).first()
if user_info_db is None:
return None
nickname, image = user_info_db
return {"nickname": nickname, "image": image}
이렇게 만들어준다.
후 이제 끝났나?
했지만 하나 더 있었다 ㅎㅎㅎ 숫자가 아니라 문자열이 들어왔을때를 처리를 안해줬다 ㅎㅎ
main.py
원래 코드가
@app.get("/users/{userId}")
def user_info(userId, db: Session = Depends(get_db)):
user_info_db = get_user_info(db, userId)
return user_info_db
에서 userId 에 타입을 명시해준다!! ㅎㅎ
@app.get("/users/{userId}")
def user_info(userId: int, db: Session = Depends(get_db)):
user_info_db = get_user_info(db, userId)
return user_info_db
그럼 오류로그 대신 422 로 알려준다
본 후기는 정보통신산업진흥원(NIPA)에서 주관하는 <AI 서비스완성! AI+웹개발 취업캠프 - 프론트엔드&백엔드> 과정 학습/프로젝트/과제 기록으로 작성되었습니다.
'코딩캠프 > AI 웹개발 취업캠프' 카테고리의 다른 글
[AI 웹개발 취업캠프] 65Day - 프로젝트 16일차 (0) | 2023.10.23 |
---|---|
[AI 웹개발 취업캠프] 64Day - 프로젝트 15일차 (0) | 2023.10.20 |
[AI 웹개발 취업캠프] 62Day - 프로젝트 13일차 (2) | 2023.10.18 |
[AI 웹개발 취업캠프] 61Day - 프로젝트 12일차 (0) | 2023.10.17 |
[AI 웹개발 취업캠프] 60Day - 프로젝트 11일차 (0) | 2023.10.16 |