JMANI

FastAPI OAuth 2 본문

카테고리 없음

FastAPI OAuth 2

jmani 2022. 7. 11. 14:57

docs: https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/#why-use-password-hashing

id/passwd DB

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    },
    "alice": {
        "username": "alice",
        "full_name": "Alice Wonderson",
        "email": "alice@example.com",
        "hashed_password": "fakehashedsecret2",
        "disabled": True,
    },
}

Simple OAuth2 with Password and Beare

app = FastAPI()


def fake_hash_password(password: str):
    return "fakehashed" + password


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
class User(BaseModel):
    username: str
    # 여러 개의 type이 허용될 수 있을 때 Union 사용
    email: Union[str, None] = None
    full_name: Union[str, None] = None
    disabled: Union[bool, None] = None


class UserInDB(User): #  상속
    hashed_password: str
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    # user_dict
    # {'username': 'alice', 'full_name': 'Alice Wonderson', 'email': 'alice@example.com', 'hashed_password': 'fakehashedsecret2', 'disabled': True}
    user_dict = fake_users_db.get(form_data.username) #  db에서 username get
    
    # 일치하는 username이 없다면,
    if not user_dict:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    
    # user
    # username='alice' email='alice@example.com' full_name='Alice Wonderson' disabled=True hashed_password='fakehashedsecret2'
    user = UserInDB(**user_dict) # BaseModel 

    # 입력한 password
    hashed_password = fake_hash_password(form_data.password) 
    
    # passwd 불일치
    if not hashed_password == user.hashed_password: 
        raise HTTPException(status_code=400, detail="Incorrect username or password")

    return {"access_token": user.username, "token_type": "bearer"}
  • username 불일치 시:
    • None 반환

로그인 성공

로그인된 User 확인

def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)


def fake_decode_token(token):
    # This doesn't provide any security at all
    # Check the next version
    user = get_user(fake_users_db, token)
    return user

# oauth2_scheme의 값을 token에 대입(str type만)
async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user

# get_current_user의 return 값을 current_user에 대입
async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user
@app.get("/users/me")
# get_current_active_user의 return 값을 current_user에 대입
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user
Comments