pip install flask-jwt-extendedJWT_SECRET_KEY = '' # string ์ผ๋ก ์ง์ ์ ์
JWT_ACCESS_TOKEN_EXPIRES = datetime.timedelta(minutes=int) # access ํ ํฐ ๋ง๋ฃ ์๊ฐ
JWT_REFRESH_TOKEN_EXPIRES = datetime.timedelta(minutes=int) # refresh ํ ํฐ ๋ง๋ฃ ์๊ฐ
# ๋ก๊ทธ์ธ ์๋ ํ์
login_attempts = {}
login_attempts_limit = 5
@bp.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
user_id = request.get_json()['userId']
user_pw = request.get_json()['pw']
# ํด๋น ์ ์ ์์ด๋ ์กฐํ
user = User.query.filter_by(user_id=user_id).first()
# ๋ก๊ทธ์ธ 5ํ ์คํจ ์
login_attempts[user_id] = login_attempts.get(user_id, 0)
if login_attempts[user_id] >= login_attempts_limit:
return 'Login attempts exceeded limit'
if user:
if check_password_hash(user.pwd.decode('utf-8'), user_pw):
# ๋ก๊ทธ์ธ ์ฑ๊ณต ์ ํด๋น ์ ์ ์์ด๋ ๋ก๊ทธ์ธ ์๋ ํ์ ์ด๊ธฐํ
login_attempts.pop(user_id, None)
# ํ ํฐ ๋ฐ๊ธ
access_token = create_access_token(identity=user_id)
refresh_token = create_refresh_token(identity=user_id)
# ๋ฆฌํ๋ ์ ํ ํฐ ์ ๋ณด
refresh_token_data = decode_token(refresh_token) # ํ ํฐ ๋์ฝ๋ฉ
created_at = datetime.fromtimestamp(refresh_token_data['iat']) # ํ ํฐ ์์ฑ์ผ
expired_at = datetime.fromtimestamp(refresh_token_data['exp']) # ํ ํฐ ๋ง๋ฃ์ผ
is_revoked = False # ํ ํฐ ์ทจ์ ์ฌ๋ถ
# ๋ฆฌํ๋ ์ ํ ํฐ ์ ๋ณด DB์ ์ฅ
existing_token = Token.query.filter_by(user_id=user_id).first()
if existing_token: # ํด๋น ์์ด๋๋ก ์ ์ฅ๋ ํ ํฐ์ด ์ด๋ฏธ ์์ผ๋ฉด ์
๋ฐ์ดํธ
existing_token.token = refresh_token
existing_token.created_at = created_at
existing_token.expired_at = expired_at
existing_token.is_revoked = is_revoked
db.session.commit()
else:
new_token = Token(token=refresh_token, user_id=user_id, created_at=created_at, expired_at=expired_at, is_revoked=is_revoked)
db.session.add(new_token)
db.session.commit()
response={
'loginRes': "Y",
'access': access_token,
'refresh': refresh_token,
'resultCode': 200,
'resultDesc': "Success",
'resultMsg': f'{user.user_name}๋ ํ์ํฉ๋๋ค.'}
return Response(response=json.dumps(response), status=200, mimetype="application/json")
else:
# ๋ก๊ทธ์ธ ์คํจ ์ ๋ก๊ทธ์ธ ์๋ ํ์ +1
login_attempts[user_id] = login_attempts.get(user_id, 0) + 1
response={
'loginRes': "N",
'access': "",
'refresh': "",
'resultCode': 401,
'resultDesc': "Unauthorized",
'resultMsg': "๋น๋ฐ๋ฒํธ๋ฅผ ๋ค์ ํ์ธํด์ฃผ์ธ์."
}
return Response(response=json.dumps(response), status=401, mimetype="application/json")
else:
# ๋ก๊ทธ์ธ ์คํจ ์ ๋ก๊ทธ์ธ ์๋ ํ์ +1
login_attempts[user_id] = login_attempts.get(user_id, 0) + 1
response={
'loginRes': "N",
'access': "",
'refresh': "",
'resultCode': 404,
'resultDesc': "Not Found",
'resultMsg': "์ผ์นํ๋ ํ์ ์ ๋ณด๊ฐ ์์ต๋๋ค."
}
return Response(response=json.dumps(response), status=404, mimetype="application/json")
else:
return 'login.html ํ์ผ ์์ฒญ'

jwt_required()๋ฅผ ์ฌ์ฉํ์ฌ api ํจ์๋ฅผ ์คํํ๊ธฐ ์ ํ ํฐ์ด ์ ํจ์ฑ์ ๊ฒ์ฆํ๊ณ ์ ํจํ ๊ฒฝ์ฐ์๋ง ํด๋น ํจ์๋ฅผ ์คํํ๋ค.
@bp.route('/my_page', methods=['GET'])
@jwt_required() # access ํ ํฐ์ ์ ํจ์ฑ์ ๊ฒ์ฆ ํ ํ ํฐ์ด ์ ํจํ๋ฉด ์ฝ๋ ์ํ
def my_page():
current_user = get_jwt_identity()
return jsonify(msg=f'Welcome, {current_user}')
@bp.route('/refresh', methods=['POST'])
@jwt_required(refresh=True)
def refresh():
refresh_token = request.headers['Authorization'].replace('Bearer ', '')
# DB์ ์๋ ๋ฆฌํ๋ ์ ํ ํฐ ์ํ ๊ฐ์ ธ์ค๊ธฐ
is_revoked = Token.query.filter_by(token=refresh_token).first().is_revoked
# ๋ฆฌํ๋ ์ ํ ํฐ์ด DB์์ ์ทจ์๋ ๊ฒฝ์ฐ(is_revoked==True)
if is_revoked:
response={
'resultCode': 401,
'resultDesc': "Unauthorized",
'resultMsg': "๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค."
}
return Response(response=json.dumps(response), status=401, mimetype="application/json")
# return url_for()
else:
current_user = get_jwt_identity()
access = create_access_token(identity=current_user)
response={
'resultCode': 200,
'resultDesc': "Success",
'access': access
}
return Response(response=json.dumps(response), status=200, mimetype="application/json")



ํ ํฐ์ ์ ์ฅํ๊ธฐ ์ํ jwt_blocklist๋ฅผ ์์ฑํ์ฌ ์ฌ์ฉํ๋ค.
jwt_blocklist = set()
@bp.route('/logout', methods=['POST'])
@jwt_required()
def logout():
jti = get_jwt()['jti'] # jti : ํ ํฐ์ ๊ณ ์ ID๋ก ์ ์ฅ
jwt_blocklist.add(jti) # jwt_blocklist : ํ ํฐ์ ๊ณ ์ ID, ํ ํฐ ์ ์ง ๊ธฐ๊ฐ, ํ ํฐ ์ ์ง ๊ธฐ๊ฐ ์ค์ ์ฌ๋ถ
return jsonify(msg='Successfully logged out.') # jwt_bloacklist์ jti๋ง ๋ฃ์ด์ฃผ๊ณ ๋๋จธ์ง ์๋ตํ๋ฉด ํ ํฐ ์ฆ์ ํ๊ดด
