사이드프로젝트

[ 기록의 정원 ] 게이트웨이 서버에 인증・인가 적용기 ( 1편 )

코줍 2024. 5. 31. 16:57

게이트웨이 서버

라우팅 역할

 

게이트웨이 서버는 HTTP 요청을 다른 프로토콜로 변환해주어서 클라쪽에서 다른 프로토콜을 신경쓰지않고 통신할 수 있게끔하는 역할을한다. 약간 중간다리 같은 역할을 한다고 생각하면 된다아아아ㅏ

게이트웨이 서버 구조
게이트웨이 서버란? 출처 : https://meetup.nhncloud.com/posts/201

 

인증인가 역할

 

뿐만 아니라, 다른 프로토콜로 접근하기 전에 유효한 회원인지 검증하는 역할을 하기도 한다.

"기록의 정원" 프로젝트는 로그인한 회원들만 서비스를 이용할 수 있기 때문에  게이트웨이 서버에서 이 인증인가 로직을 반영하기로 했다.

 

인증방식 전략 ( JWT )

세션 저장소 같은 별도의 스토리지를 두지 않고,

시크릿 키 암호화를 통해 보완성이 늘어나는 이점이 있는 JWT방식으로 회원인증을 하기로 정했다.

 

JWT 구조

 

전략

토큰의 유효성이 어긋날 경우 게이트웨이 서버쪽에서 에러를 발생시킨다.

 

- 1차로 header에 accessToken값이 없을 때 에러를 발생시킨다.

 

유효성 검증을 할 수 있는 token 자체가 없는 것이기 때문에

Unauthorized Error 대신 Client Error로 판단하여 status값을 400으로 내려 주었다.

if not access_token :
    raise HTTPException(status_code=400, detail="No access_token in Header")

 

 

- 토큰이 유효하지 않은 경우엔 401에러를 발생시킨다.

 

대신 ExpireTime 시간으로 인해 유효하지 않을 경우엔 Token has expired 라는 에러메세지를 내려주었고,

애초에 유효하지 않은 Token 값일 경우엔 Invalid Token 이라는 에러메세지를 내렸다.

def verify_jwt(self, token: str, token_type:Literal["A", "R"]):
"""유효한 토큰인지 확인"""
try:
    payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
    return payload
except jwt.ExpiredSignatureError:
    raise HTTPException(status_code=401, detail="Token has expired")
except jwt.InvalidTokenError:
    raise HTTPException(status_code=401, detail="Invalid token")

 

게이트웨이 서버에서는 DB연결을 하지 않는다. -> 회원 id값을 subject로 둔다.

 

다른 프로토콜로 라우팅 되기 전에 DB를 타지 않는 것이 추후 속도 및 성능 저하가 게이트웨이에서부터 발생하는 것을 방지할 수 있다고 판단했다. 

 

그리하여, AccessToken을 발행할 때, payload 내 subject를 회원의 ID값인 user_id값을 넣어 발행할 수 있게 했다. valid한 Token일 경우에 라우팅 될 서버쪽으로 user_id값을 header에 넣어 전달하는 방식으로 설계를 했다. 

 

 

RefreshToken이 필요해지다...to be continue...

그러나...

 

AccessToken만 있으면 된다 생각했던 나는...

RefreshToken값이 왜 필요했는가를 알게되는데...