본문 바로가기
AWS/Cognito

Flask와 Amazon Cognito를 활용한 OAuth 2.0 로그인 인증 구현하기

by drinkdog 2025. 1. 27.
반응형
이 글에서는Flask 웹 애플리케이션에서
"Amazon Cognito를 사용하여 OAuth 2.0 인증을 구현하는 방법을 상세히 알아보겠습니다."

Authlib 라이브러리를 사용하여 안전하고 신뢰성 있는 인증 시스템을 구축하는 과정을 단계별로 설명합니다.

[참고] Cognito란?

1. 필요한 패키지 설치

pip install flask authlib pyyaml

2. 전체 코드 구현

전체 코드는 github에 올려둔 것을 참고 부탁드리겠습니다.(링크)

2-1. 주요 컴포넌트 설명

  • 설정 파일(config.yaml)
    • authority: Cognito의 사용자 풀 기본 엔드포인트
    • metadata_url: OpenID Connect 설정 정보를 제공하는 엔드포인트
    • client_id/secret: Cognito 앱 클라이언트 설정에서 생성된 인증 정보
flask:
  secret_key: "your-secret-key"

cognito:
  authority: "https://cognito-idp.{region}.amazonaws.com/{user-pool-id}"
  metadata_url: "https://cognito-idp.{region}.amazonaws.com/{user-pool-id}/.well-known/openid-configuration"
  client_id: "your-client-id"
  client_secret: "your-client-secret"
  • 세션 보안
    • HttpOnly 플래그로 XSS 공격 방지
    • SameSite 속성으로 CSRF 공격 방지
    • 세션 만료 시간 설정으로 보안 강화
    • 개발/프로덕션 환경별 설정 분리
app.config.update(
    SESSION_COOKIE_SECURE=False,  # 개발환경에서는 False, 프로덕션에서는 True
    SESSION_COOKIE_HTTPONLY=True,  # JavaScript로부터 세션 쿠키 보호
    SESSION_COOKIE_SAMESITE='Lax',  # CSRF 공격 방지
    PERMANENT_SESSION_LIFETIME=3600  # 세션 만료 시간 1시간
)
  • OAuth 초기화 및 설정
    • OpenID Connect 프로토콜 지원
    • 필요한 최소 scope만 요청
    • 자동 메타데이터 설정
    • 클라이언트 인증 정보 관리
oauth = OAuth(app)
oauth.register(
    name='oidc',
    authority=config['cognito']['authority'],
    server_metadata_url=config['cognito']['metadata_url'],
    client_id=config['cognito']['client_id'],
    client_secret=config['cognito']['client_secret'],
    client_kwargs={
        'scope': 'openid email'
    }
)
  • 인증 라우트 시스템
    • 로그인 프로세스
      • 사용자가 /login 엔드포인트 접근
      • cognito 인증 페이지로 리다이렉트
      • 사용자 인증 완료 후 /authorize로 리다이렉트
      • 액세스 토큰 검증 및 사용자 정보 획득
      • 세션에 사용자 정보 저장
      • 메인 페이지로 리다이렉트
@app.route('/login')
@handle_errors
def login():
    app.logger.debug('Login process started')
    return oauth.oidc.authorize_redirect('http://localhost:5000/authorize')

@app.route('/authorize')
@handle_errors
def authorize():
    app.logger.debug('Authorization process started')
    token = oauth.oidc.authorize_access_token()
    user = token['userinfo']
    session['user'] = user
    return redirect(url_for('index'))
  • 로그아웃 프로세스
    • 세션에서 사용자 정보 제거
    • 메인 페이지로 리다이렉트
@app.route('/logout')
@handle_errors
def logout():
    """로그아웃"""
    app.logger.debug("Logging out user")
    session.pop('user', None)
    return redirect(url_for('index'))

3. OAuth 흐름

  1. 사용자가 /login 엔드포인트 접근
  2. Cognito 인증 페이지로 리다이렉트
  3. 인증 성공 시 /authorize로 리다이렉트
  4. 토큰 검증 및 사용자 정보 저장

4. Cognito Client App 설정 및 구현 결과

4-1. Cognito Client App 설정

  • OAuth resister 등록 정보는 Quick Setup Guide에서 참고할 수 있습니다.

  • callback URLs 주소는 필수로 설정을 해줘야 합니다.

4-2. 구현 결과

기본 화면
Login 성공 화면


5. 주의사항

  1. config.yaml 파일의 중요 정보 보호
  2. 프로덕션 환경에서는 SESSION_COOKIE_SECURE를 True로 설정
  3. HTTPS 사용 권장
  4. 적절한 로깅 레벨 설정

6. 문제 해결

  • 일반적으로 발생할 수 있는 CSRF 관련 에러:
    • 아래 문구는 localhost와 127.0.0.1의 도메인 차이로 인해 발생할 수 있습니다.
    • 테스트 시 callback URLs와 같은 도메인을 사용하여 테스트를 진행해야 합니다.
MismatchingStateError: mismatching_state: CSRF Warning! State not equal in request and response.

7. 결론

  • 이 구현은 Flask와 Amazon Cognito를 사용한 기본적인 OAuth 2.0 인증 시스템을 제공합니다.
  • 실제 프로덕션 환경에서는 추가적인 보안 설정과 에러 처리가 필요할 수 있습니다.

출처

https://docs.aws.amazon.com/cognito/latest/developerguide/authorization-endpoint.html

 

The redirect and authorization endpoint - Amazon Cognito

The redirect and authorization endpoint The /oauth2/authorize endpoint is a redirection endpoint that supports two redirect destinations. If you include an identity_provider or idp_identifier parameter in the URL, it silently redirects your user to the sig

docs.aws.amazon.com

https://docs.aws.amazon.com/ko_kr/cognito/latest/developerguide/federation-endpoints-oauth-grants.html

 

OAuth 2.0 권한 부여 - Amazon Cognito

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

https://docs.authlib.org/en/latest/

반응형