RESTful flask API - 로그아웃 기능 구현하기 (jwt 토큰 파괴)

반응형

flask_jwt_extended 라이브러리를 이용하여 로그아웃 기능 구현하기

  • 토큰을 이용하여 로그인 상태인 유저의 토큰을 파괴하여 로그아웃 상태로 변경
  • 즉, 토큰이 유효할 때만 로그인 상태의 권한을 누릴 수 있음
    • 토큰 (token)
      • 유저의 식별 정보를 암호화 한 것
      • 로그인을 통해 식별 정보를 토큰화
      • 토큰을 이용하여 신원을 확인
      • 로그아웃을 통해 토큰을 폐기
    • 토큰 생성
      • create_access_token( var ) : var의 데이터를 토큰화
    • 토큰 식별
      • jwt_required() : 토큰이 존재해야 다음의 코드를 수행
    • 토큰 파괴
      • @jwt.token_in_blocklist_loader : 토큰이 블록리스트에 존재하면 다음의 코드 수행
        • blacklist/blocklist : 이전에는 blacklist를 사용하였으나 이름이 변경되어 blocklist를 사용
        • payload : 토큰의 정보를 담고 있음
        • jti : jwt 토큰의 고유 ID
      • jwt_blocklist : 토큰의 파괴 기능을 담당
# 토큰이 존재하면 블록리스트에 토큰을 넣음
@jwt.token_in_blocklist_loader
def check_it_token_is_revoked(jwt_header, jwt_paypoad):
    jti = jwt_paypoad['jti']
    return jti in jwt_blocklist

# 토큰을 저장하기 위한 변수 초기화
jwt_blocklist = set()

# 토큰이 존재하면 코드 수행
# jti : 토큰을 고유ID로 저장
# jwt_blocklist : 토큰의 고유ID, 토큰 유지 기간, 토큰 유지 기간 설정 여부
# jwt_bloacklist에 jti만 넣어주고 생략하면 토큰 즉시 파괴
class UserLogoutResource(Resource) :
    @jwt_required()
    def post(self) :
        jti = get_jwt()['jti']
        jwt_blocklist.add(jti)
        return { "result" : "로그아웃이 정상처리되었습니다."}

Visual Studio Code

메인 파일 : app.py

  • 기능 : API 구축, 토큰 생성 및 관리, 리소스 경로 생성
from flask import Flask
from flask_jwt_extended import JWTManager
from flask_restful import Api

from config import Config

from resources.user import UserLogoutResource, jwt_blocklist

# API 서버를 구축하기 위한 기본 구조
app = Flask(__name__)

# 환경변수 셋팅
app.config.from_object(Config) # 만들었던 Config.py의 Config 클래스 호출

# JWT 토큰 생성
jwt = JWTManager(app)

# 로그아웃 된 토큰이 들어있는 set을 jwt에게 알림
@jwt.token_in_blocklist_loader
def check_it_token_is_revoked(jwt_header, jwt_payload):
    jti = jwt_payload['jti']
    return jti in jwt_blocklist

# restfulAPI 생성
api = Api(app)

# 경로와 리소스(api코드) 연결
api.add_resource(UserLogoutResource, '/users/logout') # 로그아웃


if __name__ == '__main__' :
    app.run()

 

환경변수 파일 : config.py

  • 기능 : 토큰의 정보 설정
class Config :
    # 암호화 키
    JWT_SECRET_KEY = 'eunbyeol0413##hello' # 주의 : 노출되면 절대 안됨
    JWT_ACCESS_TOKEN_EXPIRES = False # 토큰 유지 시간
    PROPAGATE_EXCEPTIONS = True # 예외처리를 JWT로 처리

 

추가 리소스 파일 : user.py

  • 기능 : 로그아웃 기능

+ 이 포스팅은 토큰의 파괴에 관한 글이므로 로그인 관련은 아래의 포스팅을 확인해주세요.

https://luvris2.tistory.com/196

 

API서버 - 회원을 DB에 등록하고 로그인을 할 수 있는 기능 구현하기

이번 포스팅은 DB의 user table을 이용하여 로그인을 위한 회원 등록을 하고, 로그인하는 기능을 서술합니다. 보안을 위해 유저의 식별 가능한 id는 토큰화하며 입력한 비밀번호는 암호화하여 DB에

luvris2.tistory.com

from flask_restful import Resource
from flask_jwt_extended import get_jwt, jwt_required

jwt_blocklist = set()

class UserLogoutResource(Resource) :
    # jwt_required : 토큰이 있어야 아래의 코드를 실행
    @jwt_required()
    def post(self) :

        jti = get_jwt()['jti']
        print(jti)

        jwt_blocklist.add(jti)

        return { "result" : "로그아웃이 정상처리되었습니다."}

POSTMAN

  • 토큰 미설정 후 로그아웃 - 에러 출력


  • 토큰 설정 후 로그아웃 - 정상 처리


  • 로그아웃 된 토큰을 이용하여 다시 로그아웃 - 토큰이 파괴되어 로그아웃 불가 -> 로그인 상태가 아님을 의미

 

반응형