ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • python apple, google ID TOKEN 검증기
    Python 2022. 3. 5. 18:19

    서론

    프로젝트 진행 중 구글, 애플에서 발급되는 ID token 검증을 할 일이 있어, 야매 적용해보고 정리하기 위한 글입니다.

    더 좋은 방법이 있을 수 있으므로 더 찾아보고 적용해보는 걸 추천드립니다.

    다른 곳에서 발급된 토큰으로 검증을 하지는 못 하였으므로 검증해 보는 걸 추천드립니다.

     

    회사 프로젝트간 소셜(네이버, 카카오, 구글, 애플) 회원가입, 로그인을 만드는 중에 소셜로 오는 토큰은 무조건 access token으로 소셜에 대하여 직접 검증 및 데이터를 받을 줄 알았다. 

    그러나 프론트에서 넘어오는 토큰 값은 네이버, 카카오는 예상하는 대로 access token이 넘어왔으나

    구글 애플은 id_token이라는 생소한 토큰이 넘어왔다.

     

    이것저것 검색 해보니 jwt와 같이 토큰 안에 유저 데이터가 있는 형태였다.

    그래서 토큰을 열어보면 어디에서 발급됐는지, 어떤 유저인지는 나오는데 어떻게 검증을 해야 할지를 알아봐야 했다.

     

    본론

    Goole ID token 검증

    구글은 매우 간단하다.

     

    먼저 google-auth를 설치한다.

    $ pip install google-auth

     

    그리고 아래의 코드를 써주면 검증과 토큰에 대한 정보가 넘어온다. 

    from google.oauth2 import id_token
    from google.auth.transport import requests
    
    token_val = id_token.verify_oauth2_token(
        {token},
        requests.Request(),
        audience={audience}), # optional
    )

     

    또는 아래와 같이단순히 id token request 요청으로 가능도 하다.

    그러나 audience를 포함한 검증은 불가능하다.

    requests.get("https://oauth2.googleapis.com/tokeninfo?id_token={token}")

     

    Apple ID token 검증

    검증하는 내용을 보면 애플은 https://appleid.apple.com/auth/keys 이 곳의 키 값들을 가지고 토큰의 kid 일치 및 알고리즘 검증으로 토큰 검증을 한다고 한다.

     

    apple의 토큰 검증은 딱히 라이브러리는 찾지는 못했지만, 검증 코드를 만들어져 있는 게 있어서 그 코드를 사용했다.

    소스코드는 아래 참조에 있으나 참조의 검증과정은 막히는 부분이 있어 약간의 커스텀을 하였다.

    물론 필자의 코드는 로 검증 성공할때까지 시도하는 로직이라 비효율적인 로직이다.

    더 나은 로직도 참조에 있으니 그 내용으로 사용하면 될듯하다.

     

    미리 key dictionary로 매칭하는 조금은 더 효율적인 방법으로 변경하였다.

    import jwt
    import requests
    import json
    from jwt.algorithms import RSAAlgorithm
    from rest_framework import exceptions
    
    APPLE_PUBLIC_KEY_URL = "https://appleid.apple.com/auth/keys"
    
    
    def _fetch_apple_public_key(unverified_header):
        key_payload = requests.get(APPLE_PUBLIC_KEY_URL).json()
        keys = key_payload["keys"]
    
        for key in keys:
            if key["kid"] == unverified_header["kid"]:
                return RSAAlgorithm.from_jwk(json.dumps(key))
    
    
    def _decode_apple_user_token(apple_user_token):
        unverified_header = jwt.get_unverified_header(apple_user_token)
        public_key = _fetch_apple_public_key(unverified_header)
        try:
            token = jwt.decode(
                apple_user_token,
                public_key,
                algorithms="RS256",
            )
            return token
        except Exception:
            raise exceptions.AuthenticationFailed

     

    Reference

    google

    https://stackoverflow.com/questions/359472/how-can-i-verify-a-google-authentication-api-access-token

    https://google-auth.readthedocs.io/en/stable/reference/google.oauth2.id_token.html#google.oauth2.id_token.verify_oauth2_token

     

    apple

    현재 사용중
    https://gist.github.com/davidhariri/b053787aabc9a8a9cc0893244e1549fe

    더 나은 로직
    https://gist.github.com/davidhariri/b053787aabc9a8a9cc0893244e1549fe?permalink_comment_id=3374998#gistcomment-3374998

     

    'Python' 카테고리의 다른 글

    poetry를 사용한 파이썬 dependency관리  (0) 2022.09.27

    댓글

Designed by Tistory.