Example #1
0
async def validate_internal_auth_token(
        internal_auth_token: str) -> InternalUser:
    """ Checks the validity of an internal authentication token.
		If the token is valid it also checks whether there is an
		associated user in the cache, and returns it.

		Args:
			internal_auth_token: Internal authentication token

		Returns:
			internal_user: A user object as defined in this application
	"""
    try:
        jwt_decode(internal_auth_token,
                   config.JWT_SECRET_KEY,
                   algorithms=[config.ALGORITHM])
    except PyJWTError as exc:
        raise UnauthorizedUser(f"Failed to validate auth token: {exc}")

    internal_sub_id = await cache.get(internal_auth_token)

    if not internal_sub_id:
        raise UnauthorizedUser(f"User {internal_sub_id} not cached")

    # Invalidate cache. Authentication token can only be used once
    await cache.delete(internal_auth_token)

    internal_user = await db_client.get_user_by_internal_sub_id(internal_sub_id
                                                                )

    return internal_user
Example #2
0
async def user_cred(request):
    print("!!!")
    print(jwt_decode(request.headers['authorization'][7:], "secret"))
    return json({
        "userid":
        jwt_decode(request.headers['authorization'][7:], "secret"),
        "username":
        "******"
    })
Example #3
0
async def jwt_authorization(request: Request, handler):
    origins = await _check_origins(request)
    socket = True if request.headers.get("Upgrade") == "websocket" else False
    token = request.headers.get("token")
    try:
        jwt_decode(token, **jwe_settings)
        request["token_dict"] = await _jwt_access_token_decode(token)
        if not all(request["token_dict"].values()) or not origins:
            return await _socket_unauth(request) if socket else HTTPForbidden()
    except Exception as e:
        log.error(f"Can't decode the token:\n{e}")
        return await _socket_unauth(request) if socket else HTTPForbidden()
    resp = await handler(request)
    return resp
Example #4
0
    def verify_token(self, token):
        try:
            data = jwt_decode(token, self.secret, algorithms='HS512')
        except Exception:
            data = None

        return data
Example #5
0
    def user_data(self, access_token, *args, **kwargs):
        response = kwargs.get('response')
        id_token = response.get('id_token')

        # decode the JWT header as JSON dict
        jwt_header = json.loads(
            base64.b64decode(id_token.split('.', 1)[0]).decode()
        )

        # get key id and algorithm
        key_id = jwt_header['kid']
        algorithm = jwt_header['alg']

        try:
            # retrieve certificate for key_id
            certificate = self.get_certificate(key_id)

            return jwt_decode(
                id_token,
                key=certificate.public_key(),
                algorithms=algorithm,
                audience=self.setting('KEY')
            )
        except (DecodeError, ExpiredSignature) as error:
            raise AuthTokenError(self, error)
Example #6
0
    def validate_and_return_id_token(self, id_token):
        """
        Validates the id_token according to the steps at
        http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation.
        """
        client_id, _client_secret = self.get_key_and_secret()
        decryption_key = self.setting('ID_TOKEN_DECRYPTION_KEY')
        try:
            # Decode the JWT and raise an error if the secret is invalid or
            # the response has expired.
            id_token = jwt_decode(id_token, decryption_key, audience=client_id,
                                  issuer=self.ID_TOKEN_ISSUER)
        except InvalidTokenError as err:
            raise AuthTokenError(self, err)

        # Verify the token was issued in the last 10 minutes
        utc_timestamp = timegm(datetime.datetime.utcnow().utctimetuple())
        if id_token['iat'] < (utc_timestamp - 600):
            raise AuthTokenError(self, 'Incorrect id_token: iat')

        # Validate the nonce to ensure the request was not modified
        nonce = id_token.get('nonce')
        if not nonce:
            raise AuthTokenError(self, 'Incorrect id_token: nonce')

        nonce_obj = self.get_nonce(nonce)
        if nonce_obj:
            self.remove_nonce(nonce_obj.id)
        else:
            raise AuthTokenError(self, 'Incorrect id_token: nonce')
        return id_token
Example #7
0
    def user_data(self, access_token, *args, **kwargs):
        response = kwargs.get('response')

        id_token = response.get('id_token')
        if six.PY2:
            # str() to fix a bug in Python's base64
            # https://stackoverflow.com/a/2230623/161278
            id_token = str(id_token)

        jwt_header_json = base64url_decode(id_token.split('.')[0])
        jwt_header = json.loads(jwt_header_json.decode('ascii'))

        # `kid` is short for key id
        key = self.get_public_key(jwt_header['kid'])

        try:
            return jwt_decode(
                id_token,
                key=key,
                algorithms=jwt_header['alg'],
                audience=self.setting('KEY'),
                leeway=self.setting('JWT_LEEWAY', default=0),
            )
        except (DecodeError, ExpiredSignature) as error:
            raise AuthTokenError(self, error)
Example #8
0
def get_access_token(social_auth):
    '''Return the access token for the given user, after ensuring that it
    has not expired, or refreshing it if so.'''

    access_token = social_auth.extra_data['access_token']
    decoded_token = jwt_decode(access_token,
                               options={
                                   'verify_signature': False,
                                   'verify_nbf': False,
                                   'verify_exp': False,
                                   'verify_aud': False
                               })
    expires_on = decoded_token['exp']

    if expires_on - 60 <= int(time.time()):
        if 'refresh_token' in social_auth.extra_data:
            refresh_token = social_auth.extra_data['refresh_token']
            backend = social_auth.get_backend_instance()
            new_token_response = backend.refresh_token(token=refresh_token)
            access_token = new_token_response['access_token']
            social_auth.extra_data['access_token'] = access_token
            social_auth.save()
        else:
            return

    return access_token
Example #9
0
def decode(token,
           options=DEFAULT_DECODE_OPTIONS,
           check_claims=MANDATORY_CLAIMS):
    """Decode JWT payload and check for 'jti', 'sub' claims."""
    decoded = jwt_decode(token, settings.SECRET_KEY, options=options)
    check_mandatory_claims(decoded, claims=check_claims)
    return decoded
Example #10
0
async def _jwt_access_token_decode(token):
    try:
        decoded = jwt_decode(token.encode(), **jwe_settings)
        return {"expires": decoded.get("expires"), "session_id": decoded.get("session_id")}
    except DecodeError as e:
        log.error(e)
        raise InvalidTokenError("Invalid token")
Example #11
0
    def __call__(self, scope):

        # Get the token
        token = ''
        try:
            token = dict(scope['headers'])[b'authorization'].decode(
                'utf8').split(' ')[1]
        except KeyError as e:
            return self.inner(dict(scope, user='******'))

        # Try to authenticate the user
        try:
            # This will automatically validate the token and raise an error if token is invalid
            UntypedToken(token, 34)
        except (InvalidToken, TokenError) as e:
            # Token is invalid
            return self.inner(dict(scope, user='******'))
        else:
            #  Then token is valid, decode it
            decoded_data = jwt_decode(token,
                                      settings.SECRET_KEY,
                                      algorithms=["HS256"])
            # Will return a dictionary like -
            # {
            #     "token_type": "access",
            #     "exp": 1568770772,
            #     "jti": "5c15e80d65b04c20ad34d77b6703251b",
            #     "user_id": 6
            # }

            # Get the user using ID
            # Return the inner application directly and let it run everything else
            user = Member.objects.get(auth=decoded_data['user_id'])
            print(user, 3324)
        return self.inner(dict(scope, user=decoded_data['user_id']))
Example #12
0
    def user_data(self, access_token, *args, **kwargs):
        response = kwargs.get('response')

        id_token = response.get('id_token')
        if six.PY2:
            # str() to fix a bug in Python's base64
            # https://stackoverflow.com/a/2230623/161278
            id_token = str(id_token)

        jwt_header_json = base64url_decode(id_token.split('.')[0])
        jwt_header = json.loads(jwt_header_json.decode('ascii'))

        # `kid` is short for key id
        key = self.get_public_key(jwt_header['kid'])

        try:
            return jwt_decode(
                id_token,
                key=key,
                algorithms=jwt_header['alg'],
                audience=self.setting('KEY'),
                leeway=self.setting('JWT_LEEWAY', default=0),
            )
        except (DecodeError, ExpiredSignature) as error:
            raise AuthTokenError(self, error)
    def __call__(self, scope):
        # Close old database connections to prevent usage of timed out connections
        close_old_connections()
        headers = dict(scope['headers'])
        if b'Token' in headers:
            # try:
            #     token_name, token_key = headers[b'token'].decode().split()
            #     if token_name == 'Token':
            #         token = Token.objects.get(key=token_key)
            #         scope['user'] = token.user
            #         # close_old_connections()
            # except Token.DoesNotExist:
            #     scope['user'] = AnonymousUser()
            token = headers[b'Token'].decode()
        else:
            # Get the token
            token = parse_qs(scope["query_string"].decode("utf8"))["token"][0]

        # Try to authenticate the user
        try:
            # This will automatically validate the token and raise an error if token is invalid
            UntypedToken(token)
        except (InvalidToken, TokenError) as e:
            # Token is invalid
            # print(e)
            user = AnonymousUser()
        else:
            #  Then token is valid, decode it
            decoded_data = jwt_decode(token, settings.SECRET_KEY, algorithms=["HS256"])
            # print(decoded_data)
            # Get the user using ID
            user = get_user_model().objects.get(id=decoded_data["user_id"])

        # Return the inner application directly and let it run everything else
        return self.inner(dict(scope, user=user))
Example #14
0
async def validate_internal_access_token(
        internal_access_token: str) -> InternalUser:
    """ Checks the validity of an internal access token. If the token
		is valid it also checks whether there is an associated user
		in the database, and returns it.

		Args:
			internal_access_token: Internal access token

		Returns:
			internal_user: A user object as defined in this application
	"""
    try:
        payload = jwt_decode(internal_access_token,
                             config.JWT_SECRET_KEY,
                             algorithms=[config.ALGORITHM])

        internal_sub_id: str = payload.get("sub")
        if internal_sub_id is None:
            raise UnauthorizedUser("Missing 'sub' id from access token")

    except PyJWTError as exc:
        raise UnauthorizedUser(f"Failed to validate access token: {exc}")

    internal_user = await db_client.get_user_by_internal_sub_id(internal_sub_id
                                                                )

    if internal_user is None:
        raise UnauthorizedUser(f"User {internal_sub_id} does not exist")

    return internal_user
Example #15
0
 def is_valid_token(self):
     '''
     check if the given token is still valid
     TODO check whether token was revoked
     '''
     try:
         jwt_decode(self.token,
                    options={
                        'verify_signature': False,
                        'verify_nbf': False,
                        'verify_exp': True,
                        'verify_aud': False
                    })
         return True
     except ExpiredSignatureError as ex:
         return False
Example #16
0
 def decodeRequest(
     self, recquiredFields: Sequence[str] = tuple()) -> Dict[str, Any]:
     request = self.get_body_argument(
         'request',
         None) if self.request.method != 'GET' else self.get_argument(
             'request', None)
     if not request:
         raise tornado.web.HTTPError(400, "Bad request")
     try:
         decoded_request = jwt_decode(
             request,
             key=self.settings['api_key'],
             audience=
             f'{self.settings["options"].base_uri}{self.request.path}',
             options={
                 'require_exp': True,
                 'require_nbf': True
             })
         if 'jti' not in decoded_request:
             raise MissingRequiredClaimError('jti')
         self.jti = decoded_request['jti']
     except InvalidTokenError as e:
         logging.warning(f"Invalid token: {e}")
         raise tornado.web.HTTPError(403, "Invalid request")
     logging.debug(f"Request: {decoded_request}")
     if not all(param in decoded_request for param in recquiredFields):
         raise tornado.web.HTTPError(400, "Too few request parameters")
     return decoded_request
Example #17
0
    def __call__(self, scope):

        # Close old database connections to prevent usage of timed out connections
        close_old_connections()

        # Get the token
        token = parse_qs(scope["query_string"].decode("utf8"))["token"][0]

        # Try to authenticate the user
        try:
            # This will automatically validate the token and raise an error if token is invalid
            UntypedToken(token)
        except (InvalidToken, TokenError) as e:
            # Token is invalid
            print(e)
            return None
        else:
            #  Then token is valid, decode it
            decoded_data = jwt_decode(token,
                                      settings.SECRET_KEY,
                                      algorithms=["HS256"])
            print(decoded_data)
            # Will return a dictionary like -
            # {
            #     "token_type": "access",
            #     "exp": 1568770772,
            #     "jti": "5c15e80d65b04c20ad34d77b6703251b",
            #     "user_id": 6
            # }

            # Get the user using ID
            user = get_user_model().objects.get(id=decoded_data["user_id"])

        # Return the inner application directly and let it run everything else
        return self.inner(dict(scope, user=user))
Example #18
0
    def _authenticate_credentials(self, request, token):
        """
        Try to authenticate the given credentials. If authentication is
        successful, return the user and token. If not, throw an error.
        """

        try:
            payload = jwt_decode(token, settings.SECRET_KEY)
        except DecodeError:
            msg = 'Invalid authentication. Could not decode token.'
            raise AuthenticationFailed(msg)

        User = get_user_model()

        try:
            id_ = payload.get('id', None)
            user = User.objects.get(pk=id_)
        except User.DoesNotExist:
            msg = 'No user matching this token was found.'
            raise AuthenticationFailed(msg)

        if not user.is_active:
            msg = 'This user has been deactivated.'
            raise AuthenticationFailed(msg)

        return (user, token)
    async def __call__(self, scope, receive, send):
        # close_old_connections()

        token = ''

        for name, value in scope.get("headers", []):
            if name == b"authorization":
                try:
                    token = value.decode("latin1").split()[1]
                except IndexError:
                    token = ''
                break

        # token = parse_qs(scope["query_string"].decode("utf8"))["token"][0]

        try:
            UntypedToken(token)
        except (InvalidToken, TokenError) as e:
            print(e)
            scope['user'] = AnonymousUser()
        else:
            decoded_data = jwt_decode(token,
                                      settings.SECRET_KEY,
                                      algorithms=["HS256"])
            scope['user'] = await self.get_user(decoded_data)
            # print('middl', scope['user'])

        return await super().__call__(scope, receive, send)
Example #20
0
    def validate_and_return_id_token(self, id_token):
        """
        Validates the id_token according to the steps at
        http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation.
        """
        client_id, _client_secret = self.get_key_and_secret()
        decryption_key = self.setting('ID_TOKEN_DECRYPTION_KEY')
        try:
            # Decode the JWT and raise an error if the secret is invalid or
            # the response has expired.
            id_token = jwt_decode(id_token,
                                  decryption_key,
                                  audience=client_id,
                                  issuer=self.ID_TOKEN_ISSUER,
                                  algorithms=['HS256'])
        except InvalidTokenError as err:
            raise AuthTokenError(self, err)

        # Verify the token was issued in the last 10 minutes
        utc_timestamp = timegm(datetime.datetime.utcnow().utctimetuple())
        if id_token['iat'] < (utc_timestamp - 600):
            raise AuthTokenError(self, 'Incorrect id_token: iat')

        # Validate the nonce to ensure the request was not modified
        nonce = id_token.get('nonce')
        if not nonce:
            raise AuthTokenError(self, 'Incorrect id_token: nonce')

        nonce_obj = self.get_nonce(nonce)
        if nonce_obj:
            self.remove_nonce(nonce_obj.id)
        else:
            raise AuthTokenError(self, 'Incorrect id_token: nonce')
        return id_token
Example #21
0
async def verify_jwt_token(request: Request, handler):
    if any([
            request.path.startswith(path) and request.method == method
            for path, method in WITHOUT_VERIFY
    ]):
        resp = await handler(request)
        return resp

    else:  # 对jwt token检验
        try:
            if match('/ws/.*', request.path):
                token = request.query['token']
            else:
                token = request.headers.get('Authorization').split(' ')[-1]
            app = request.app
        except (AttributeError, KeyError, IndexError):
            return code_response(InvalidTokenResponse)

        try:
            content = jwt_decode(token,
                                 app['config']['jwt-secret'],
                                 algorithms=['HS256'])
            # 检查功能模块的权限
            for pattern in MODULE_PERMISSION.keys():
                if match(pattern, request.path):
                    if content.get('rol') & MODULE_PERMISSION[pattern]:
                        break
                    else:
                        return code_response(RepetitionLoginResponse)
            # 检测重复登录
            try:
                _key = '{}:{}:jwt'.format(content.get('name'),
                                          content.get('dep'))
                _value = await request.app['redis'].get(_key)
                if _value:
                    assert token == _value
            except AssertionError:
                return code_response(InvalidTokenResponse)

            request['jwt_content'] = content
            if await app['black_bf'].is_contain(token):
                # 是否在缓冲表中
                if await app['redis'].exists('it:tmp-list:{}'.format(token)):
                    resp = await handler(request)
                    resp.headers['jwt_new_token'] = await app['redis'].get(
                        'it:tmp-list:{}'.format(token))
                    return resp
                else:
                    return code_response(InvalidTokenResponse)
            else:
                resp = await handler(request)
                # 离过期不足5分钟,更新token
                if content.get('exp') <= (datetime.now() +
                                          timedelta(minutes=5)).timestamp():
                    # 在header加上新token,通过前端axios拦截下来,然后更新
                    resp.headers['jwt_new_token'] = await update_token(
                        content, token, app)
                return resp
        except (InvalidSignatureError, ExpiredSignatureError, DecodeError):
            return code_response(InvalidTokenResponse)
Example #22
0
    def user_data(self, access_token, *args, **kwargs):
        response = kwargs.get('response')
        id_token = response.get('id_token')

        # decode the JWT header as JSON dict
        jwt_header = json.loads(
            base64.b64decode(id_token.split('.', 1)[0]).decode()
        )

        # get key id and algorithm
        key_id = jwt_header['kid']
        algorithm = jwt_header['alg']

        try:
            # retrieve certificate for key_id
            certificate = self.get_certificate(key_id)

            return jwt_decode(
                id_token,
                key=certificate.public_key(),
                algorithms=algorithm,
                audience=self.setting('KEY')
            )
        except (DecodeError, ExpiredSignature) as error:
            raise AuthTokenError(self, error)
Example #23
0
    def from_token(token):
        """Get AccessToken from token string

        :param UUID or str token: JWT encoded token or token UUID string, either dashed or not, or UUID object
        :rtype: AccessToken or None
        """
        if isinstance(token, str):
            try:
                uuid_object = UUID(token)
            except ValueError:  # token is invalid UUID, may be JWT
                try:
                    jwt_decoded = jwt_decode(jwt=token, verify=False)
                    uuid_object = UUID(jwt_decoded["yggt"])
                except (jwt_exceptions.DecodeError,
                        jwt_exceptions.InvalidAlgorithmError, ValueError):
                    return None
                else:
                    return AccessToken.get(uuid=uuid_object)
            else:  # token is valid UUID
                return AccessToken.get(uuid=uuid_object)

        elif isinstance(token, UUID):
            return AccessToken.get(uuid=token)

        return None
Example #24
0
    async def __call__(self, scope, receive, send):
        # Close old database connections to prevent usage of timed out connections
        close_old_connections()

        try:
            token = parse_qs(scope["query_string"].decode("utf8"))["bearer"][0]
        except KeyError:
            # Token is not presented
            return None
        try:
            # This will automatically validate the token and raise an error if token is invalid
            UntypedToken(token)
        except (InvalidToken, TokenError) as e:
            # Token is invalid
            return None
        else:
            #  Then token is valid, decode it
            decoded_data = jwt_decode(token,
                                      settings.SECRET_KEY,
                                      algorithms=["HS256"])
            # Get the user using ID
            scope["user"] = await get_user_model().get_by_pk_from_async(
                decoded_data["user_id"])

        # Return the inner application directly and let it run everything else
        return await super().__call__(scope, receive, send)
Example #25
0
 def user_data(self, access_token, *args, **kwargs):
     response = kwargs.get("response")
     id_token = response.get("id_token")
     try:
         decoded_id_token = jwt_decode(id_token, verify=False)
     except (DecodeError, ExpiredSignature) as de:
         raise AuthTokenError(self, de)
     return decoded_id_token
Example #26
0
 def decode(cls, private_key: RSAPrivateKey, token_bytes: str) -> str:
     public_bytes = private_key.public_key().public_bytes(
         encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo)
     token = jwt_decode(token_bytes,
                        public_bytes,
                        algorithms=['RS256'],
                        verify=False)
     return token['sub']
Example #27
0
    def validate(self, attrs):
        # UntypedToken(attrs['token'])
        data = jwt_decode(attrs['token'],
                          settings.SECRET_KEY,
                          algorithms=['HS256'])
        data = {'id': data['user_id']}

        return data
Example #28
0
 def user_data(self, access_token, *args, **kwargs):
     response = kwargs.get('response')
     id_token = response.get('id_token')
     try:
         decoded_id_token = jwt_decode(id_token, verify=False)
     except (DecodeError, ExpiredSignature) as de:
         raise AuthTokenError(self, de)
     return decoded_id_token
Example #29
0
    def decode(encoded,
               secret='zn1xct1RFpGvuyXC3E9BreRjVl9x1GxQ',
               algorithm="HS512"):

        try:
            decoded = jwt_decode(encoded, secret, algorithm=algorithm)
        except InvalidTokenError as error:
            decoded = False

        return decoded
Example #30
0
 def verify_password_reset_token(token):
     """Verifies that a provided password reset token is valid."""
     try:
         email = jwt_decode(token,
                            current_app.config['SECRET_KEY'],
                            algorithms=['HS256'
                                        ])['password_reset_for_email']
     except:
         return
     return User.query.join('emails').filter_by(email=email).first()
Example #31
0
def get_decoded_jwt_token(token):
    try:
        return jwt_decode(token,
                          __JWT_SECRET__,
                          algorithms=[__JWT_ALGORITHM__])
    except DecodeError as error:
        raise HTTPError(400, "Invalid Token. (error: " + str(error) +
                        ")")  # 400 - Bad request
    except InvalidAlgorithmError as error:
        raise HTTPError(400, "Invalid Token. (error: " + str(error) +
                        ")")  # 400 - Bad request
Example #32
0
def read_yggt(access_token_string: str):
    """
    :param access_token_string: 32 or 36 char UUID or JWT
    :return: yggt value
    """
    if len(access_token_string) == 32:
        return access_token_string
    elif len(access_token_string) == 36:
        return access_token_string.replace("-", "")
    else:
        return jwt_decode(jwt=access_token_string, verify=False)["yggt"]
Example #33
0
 def get_email_by_token(token):
     """Returns the email matching the verification token."""
     try:
         decoded_token = jwt_decode(token,
                                    current_app.config['SECRET_KEY'],
                                    algorithms=['HS256'])
         email = decoded_token['email']
         user_id = decoded_token['user_id']
     except:
         return None
     return Email.query.filter_by(email=email, user_id=user_id).first()
Example #34
0
def validate_token_getpayload(token):
    
    secret = get_secret()
    token_bytes = token.encode()
    try:
        payload = jwt_decode(token_bytes, secret, algorithms=['HS256'])
    # token incorrect
    except InvalidTokenError:
        raise AccessError(description = "Token was not generated by server!")

    return payload
Example #35
0
    def validate_and_return_id_token(self, id_token):
        """
        Validates the id_token according to the steps at
        http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation.
        """
        client_id, _client_secret = self.get_key_and_secret()

        decode_kwargs = {
            'algorithms': ['HS256'],
            'audience': client_id,
            'issuer': self.ID_TOKEN_ISSUER,
            'key': self.setting('ID_TOKEN_DECRYPTION_KEY'),
            'options': {
                'verify_signature': True,
                'verify_exp': True,
                'verify_iat': True,
                'verify_aud': True,
                'verify_iss': True,
                'require_exp': True,
                'require_iat': True,
            },
        }
        decode_kwargs.update(self.setting('ID_TOKEN_JWT_DECODE_KWARGS', {}))

        try:
            # Decode the JWT and raise an error if the secret is invalid or
            # the response has expired.
            id_token = jwt_decode(id_token, **decode_kwargs)
        except InvalidTokenError as err:
            raise AuthTokenError(self, err)

        # Verify the token was issued within a specified amount of time
        iat_leeway = self.setting('ID_TOKEN_MAX_AGE', self.ID_TOKEN_MAX_AGE)
        utc_timestamp = timegm(datetime.datetime.utcnow().utctimetuple())
        if id_token['iat'] < (utc_timestamp - iat_leeway):
            raise AuthTokenError(self, 'Incorrect id_token: iat')

        # Validate the nonce to ensure the request was not modified
        nonce = id_token.get('nonce')
        if not nonce:
            raise AuthTokenError(self, 'Incorrect id_token: nonce')

        nonce_obj = self.get_nonce(nonce)
        if nonce_obj:
            self.remove_nonce(nonce_obj.id)
        else:
            raise AuthTokenError(self, 'Incorrect id_token: nonce')
        return id_token
    def user_data(self, access_token, *args, **kwargs):
        response = kwargs.get('response')

        # str() to fix a bug in Python's base64 https://stackoverflow.com/a/2230623/161278
        id_token = str(response.get('id_token'))

        jwt_header_json = base64url_decode(id_token.split('.', 1)[0])

        # Decode the JWT header as JSON dict
        jwt_header = json.loads(jwt_header_json)
        key = self._get_public_key(jwt_header['kid'])  # `kid` is short for key id

        try:
            # Retrieve certificate for key_id
            return jwt_decode(
                id_token,
                key=key,
                algorithms=jwt_header['alg'],  # algorithm = 'RS256'
                audience=self.setting('KEY'),
                leeway=self.setting('JWT_LEEWAY', default=0),
            )
        except (DecodeError, ExpiredSignature) as error:
            raise AuthTokenError(self, error)
def get_access_token(social_auth):
    '''Return the access token for the given user, after ensuring that it
    has not expired, or refreshing it if so.'''

    access_token = social_auth.extra_data['access_token']
    decoded_token = jwt_decode(access_token, options={'verify_signature': False,
                                                      'verify_nbf': False,
                                                      'verify_exp': False,
                                                      'verify_aud': False})
    expires_on = decoded_token['exp']

    if expires_on - 60 <= int(time.time()):
        if 'refresh_token' in social_auth.extra_data:
            refresh_token = social_auth.extra_data['refresh_token']
            backend = social_auth.get_backend_instance()
            new_token_response = backend.refresh_token(token=refresh_token)
            access_token = new_token_response['access_token']
            social_auth.extra_data['access_token'] = access_token
            social_auth.save()
        else:
            return

    return access_token