수 많은 우문은 현답을 만든다

API 서비스 개발(1) - JWT 본문

토이 프로젝트

API 서비스 개발(1) - JWT

aiden.jo 2024. 7. 29. 23:57

개요

Python과 Fast API를 사용해서 json 형태의 API를 제공하는 서비스를 개발하려고 한다.

오늘은 API 요청의 가장 기본이 되는 JWT(Json Web Token) 방식을 구현해보고 자세한 과정들을 기록해 공유하고자 한다.

 

환경 구성

우선 아래 라이브러리들을 설치해준다.

pip install fastapi

pip install uvicorn

pip install pyjwt

1. fastapi : python 3.6 이상에서 동작하는 경량, 고성능 백엔드 프레임워크

2. uvicorn : FastAPI를 실행하기 위한 ASGI 서버

  * ASGI(Asynchronous Server Gateway Interface) : 비동기 웹서버

  * WSGI(Web Server Gateway Interface) : 동기 웹서버

 

 

소스코드 작성

이제는 소스코드를 작성해보자.

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel
from datetime import datetime, timedelta
import jwt

# JWT 토큰 생성에 사용할 시크릿 키
SECRET_KEY = "your_secret_key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

app = FastAPI()

# OAuth2PasswordBearer는 "Bearer" 토큰 형식의 OAuth2 인증을 기대합니다
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

# 사용자 모델 (데모를 위해 하드코딩된 사용자)
class User(BaseModel):
    username: str

# 사용자 인증 함수 (여기서는 간단히 하드코딩된 사용자만 인증)
def authenticate_user(username: str, password: str):
    if username == "testuser" and password == "testpassword":
        return User(username=username)
    return None

# JWT 토큰 생성 함수
def create_access_token(data: dict, expires_delta: timedelta = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

# 로그인 엔드포인트 (JWT 토큰 발행)
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user = authenticate_user(form_data.username, form_data.password)
    if not user:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    return {"access_token": access_token, "token_type": "bearer"}

# 보호된 엔드포인트 (JWT 토큰 필요)
@app.get("/users/me")
async def read_users_me(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(
        status_code=401,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
    except jwt.PyJWTError:
        raise credentials_exception
    return {"username": username}

 

 

 

실행

이제 실행 해보겠습니다.

uvicorn main:app --reload

 

앗 ! 아래와 같은 에러가 발생한다면, 파이썬 라이브러리 실행 명령어들이 아직 환경변수로 등록되지 않은 것이다.

PS C:\Users\> uvicorn main:app --reload
uvicorn : 'uvicorn' 용어가 cmdlet, 함수, 스크립트 파일 또는 실행할 수 있는 프로그램 이름으로 인식되지 않습니다
. 이름이 정확한지 확인하고 경로가 포함된 경우 경로가 올바른지 검증한 다음 다시 시도하십시오.

 

1. script의 위치를 확인한다

pip show uvicorn

# 아래와 같은 경로가 라이브러리들의 위치이며 이 위치를 환경 변수로 등록해야한다.
C:\Users\<YourUsername>\AppData\Local\Programs\Python\PythonXX\Scripts

 

2. 위 경로를 복사하고 아래 절차대로 환경 변수를 등록한다

  * 시작 > 환경 변수 편집 > Path > 새로 추가

 

3. 다시 실행해보자

PS C:\Users\HZ39P7\weatherpia> uvicorn main:app --reload
INFO:     Will watch for changes in these directories: ['C:\\Users\\HZ39P7\\weatherpia']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [36332] using WatchFiles
INFO:     Started server process [31600]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

이제 잘 실행 되었다 !

 

실행 결과

브라우저로 Fast API 서버의 Swagger에 접속해보자

http://127.0.0.1:8000/docs

 

Swagger

 

테스트

이제 만든 API들을 테스트 해보자

1. 로그인

 

우선 로그인 API인 POST /token API를 클릭해보자.

 

 

초록색 영역을 클릭하면 아래와같은 화면이 나오고, username, password를 입력한다.

 

 

아래와 같이 Token 결과를 얻을 수 있다.

 

 

이제 이 api들을 호출해서 사용하면 된다.

감사합니다.

'토이 프로젝트' 카테고리의 다른 글

메세지 큐 - 1. MQ 비교 및 설치  (2) 2024.11.06
웹서비스 성능 향상 방법  (0) 2024.10.30
API 서비스 개발(3) - API  (0) 2024.08.03
API 서비스 개발(2) - DB  (0) 2024.08.01