개발학습일지

[Restful API] Flask에서 JWT 사용 _ JWT 설치하기, 토큰을 적용한 회원가입 API 본문

Restful API

[Restful API] Flask에서 JWT 사용 _ JWT 설치하기, 토큰을 적용한 회원가입 API

처카푸 2024. 5. 22. 17:11

Flask에서 JWT 사용하기 _ 회원가입 API 만들기

 

1. JWT 사용하기 (설치, 관련 변수 처리)

- 설치하는 명령어

$ pip install flask-jwt-extended

- jwt 관련 매뉴얼 사이트

https://flask-jwt-extended.readthedocs.io/en/stable/token_locations.html

 

Configuration Options — flask-jwt-extended 4.6.0 documentation

These are only applicable if a route is configured to accept JWTs via cookies. JWT_COOKIE_DOMAIN Value to use for cross domain cookies. For example, if JWT_COOKIE_DOMAIN is ".example.com", the cookies will be set so they are readable by the domains www.exa

flask-jwt-extended.readthedocs.io

1-1. 컨픽(config.py) 파일  Config 클래스 안에 JWT관련 변수를 세팅한다.

class Config :
    # JWT 관련 변수를 셋팅
    JWT_SECRET_KEY = '보안키 작성'
    JWT_ACCESS_TOKEN_EXPIRES = False # False = 만료없이 설정 하겠다
    PROPAGATE_EXCEPTIONS = True # 에러가 나면 보여줄것

 

 

2. 회원가입 API 만들기

- 토큰 생성해서 처리하는 코드를 작성

2-1. 포스트맨에서 회원가입 API 만들기

- 회원가입 정보 입력한다.

포스트맨 회원가입 API

2-2. app.py Entry point에 경로 만들기

# 경로(path)와 리소스(API 코드)를 연결한다.
# Entry point
api.add_resource( UserRegisterResource , '/users/register' )

2-3. resources/user.py에 API 코드 작성

import datetime
from email_validator import EmailNotValidError, validate_email
from flask import request
from flask_jwt_extended import create_access_token
from flask_restful import Resource
from mysql.connector import Error

from mysql_connection import get_connection
from utils import check_password, hash_password


class UserRegisterResource(Resource):

    def post(self) :
        # 1. 클라이언트가 보낸 데이터를 받아준다.
        data = request.get_json()
        print(data)

        # 2. 데이터가 모두 있는지 확인 _없으면 바로 리턴
        # 두가지 코드로 작성 가능
        #if 'email' not in data or 'username' not in data or 'password' not in data:
        #    return {"result":"fail"}, 400
        
        #if data['email'].strip() == '' or data['username'].strip() == '' or data['password'].strip() == '' :
        #    return {"result":"fail"}, 400

        # 딕셔너리 get함수 사용 CPU 동작 순서대로 작성
        # strip() 공백 제거는 섬세함의 차이이다.
        if data.get('email') is None or data.get('email').strip() == '' or \
            data.get('username') is None or data.get('username').strip() == '' or \
            data.get('password') is None or data.get('password').strip() == '' :
            return {"result":"fail"}, 400
        
        # 3. 이메일 주소 형식이 올바른지 확인
        try :
            validate_email(data['email']) 
        except EmailNotValidError as e :
            return {"result":"fail", "error":str(e)}, 400
        
        # 4. 비밀번호 길이가 유효하지 체크한다.
        #    예) 비번은 4자리 이상 12자리 이하
        if len(data['password']) < 4 or len(data['password']) > 12 :
            return {"result":"fail"}, 400
        
        # 5. 비밀번호를 암호화
        # utils.py 에 만들어둔 hash_password() 함수
        password = hash_password( data['password'] )
        print(password)

        # 6. DB에 저장한다.
        try :
            connection = get_connection()
            # 암호화된 패스워드 변수로 넣어줘야한다.
            query = '''
                    insert into user
                    (username, email, password)
                    values
                    (%s, %s, %s);'''
            recode = (data['username'], data['email'], password)
            cursor = connection.cursor()
            cursor.execute( query, recode )

            connection.commit()

            ### DB에 회원가입하여, user 테이블에 insert된 후,
            ### 이 user테이블의 id 값을 가져와야 한다.
            user_id = cursor.lastrowid
            
            cursor.close()
            connection.close()

        except Error as e :
            if cursor is not None :
                cursor.close()
            if connection is not None :
                connection.close()
            return {"result":"fail", "error":str(e)}, 500
        
        # 6-2. user_id를 바로 클라이언트에게 보내면 안되고,
        #      JWT로 암호화해서, 인증토큰을 보내야 한다.
        #      여러개는 딕셔너리로 입력한다.
        access_token = create_access_token(user_id)


        #7. 응답할 데이터를 JSON으로 만들어서 응답. _user_id 도 같이 보내준다.
        return {"result":"success", "access_token":access_token}, 200

 

2-4. 포스트맨에서 회원가입 잘 되는지 테스트

- success와 함께 암호화된 인증토큰이 나온다.

   -> 바로 인증토큰이 발행되어 추가 로그인 없이 서비스 이용이 가능하다.

회원가입 정상 작동

 

 

 


* JWT 라이브러리에서 제공하는 함수들

- create_access_token() : 토큰으로 만든다. _ 회원가입 또는 로그인 API에서 일반적으로 사용한다.

- @jwt_required(optional=False) : 무조건 토큰 필요하다.라는 의미, 옵셔널을 True로 하면 상관없다는 뜻이다.

- get_jwt_identity() : 토큰을 다시 원본데이터로 변환시켜서 가져온다.

 

* 회원가입 API에서 토큰 생성 처리하는 코드 관련 라이브러리

- 이메일 주소 확인하기 위한 라이브러리 (https://msdev-st.tistory.com/139)

- 비밀번호 암호화 하기 위해 pbkdf2_sha256 사용 (https://msdev-st.tistory.com/138)

 

* 인증토큰 시간 만료하는 코드

- expires_delta = 인증토튼 만료 시간을 주는 것. 함수 안에 시간은 개발자가 정해서 작성한다.

create_access_token(user_id, expires_delta= datetime.timedelta(minutes=30))