Как найти уровень залога пользователя на патреоне, используя django-allauth для аутентификации

Я использую django-allauth для аутентификации пользователей (использует API Патреона v1), который добавляет json в базу данных с информацией ниже. Я хотел бы показывать дополнительный контент на сайте, если обещание пользователя соответствует определенному уровню (или выше).

{
  "attributes": {
    "about": null,
    "can_see_nsfw": true,
    "created": "2019-05-20T20:29:02.000+00:00",
    "default_country_code": null,
    "discord_id": null,
    "email": "[email protected]",
    "facebook": null,
    "facebook_id": null,
    "first_name": "Adm",
    "full_name": "Adm Nsm",
    "gender": 0,
    "has_password": true,
    "image_url": "https://c8.patreon.com/2/200/21383296",
    "is_deleted": false,
    "is_email_verified": false,
    "is_nuked": false,
    "is_suspended": false,
    "last_name": "Nsm",
    "social_connections": {
      "deviantart": null,
      "discord": null,
      "facebook": null,
      "instagram": null,
      "reddit": null,
      "spotify": null,
      "twitch": null,
      "twitter": null,
      "youtube": null
    },
    "thumb_url": "https://c8.patreon.com/2/200/21383296",
    "twitch": null,
    "twitter": null,
    "url": "https://www.patreon.com/user?u=21383296",
    "vanity": null,
    "youtube": null
  },
  "id": "21383296",
  "relationships": {
    "pledges": {
      "data": [
        {
          "id": "24461189",
          "type": "pledge"
        }
      ]
    }
  },
  "type": "user"
}

Сначала я думал, что Relations.pledges.data.id будет иметь идентификатор текущего уровня, и с его помощью мне удалось добавить дополнительный блок контента для конкретного пользователя, но, видимо, это было только желаемое за действительное; после тестирования со второй учетной записью идентификатор, который я считал уровнем залога, кажется, каждый раз отличается. Я предполагаю, что мне может понадобиться запросить дополнительную информацию у API Патреона, но я не знаю, как вернуть то, что мне нужно.

Обновлено:

Из того, что я могу собрать, мне нужно будет запросить в настоящее время_entitled_tiers у /api/oauth2/v2/members/{id}.

Проблема в том, что требуемый идентификатор не совпадает с идентификатором, который я получаю после входа пользователя в систему. Поэтому мне сначала нужно использовать сгенерированный токен доступа oauth и GET /api/oauth2/v2/идентификация для длинного идентификационного номера.

Моя текущая проблема заключается в том, что когда я пытаюсь получить идентификатор из /api/oauth2/v2/identity, я получаю код ошибки 401:

<Response [401]>
{'errors': [{'code': 1, 'code_name': 'Unauthorized', 'detail': "The server could not verify that you are authorized to access the URL requested.  You either supplied the wrong credentia
ls (e.g. a bad password), or your browser doesn't understand how to supply the credentials required.", 'id': 'b298d8b1-73db-46ab-b3f4-545e6f934599', 'status': '401', 'title': 'Unauthori
zed'}]}

Что я отправляю:

headers = {"authorization": "Bearer " + str(access_token)}  # User's Access Token
req = requests.get("https://patreon.com/api/oauth2/v2/identity?include=memberships", headers=headers)

Если я получу правильный идентификатор через /api/oauth2/v2/кампании/{campaign_id}/члены, я могу запросить у /api/oauth2/v2/members/{id} и получить то, что мне нужно, но этот промежуточный шаг с использованием вошедшего в систему пользователя для получения его идентификатора ускользает от меня.

Спасибо.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
6
0
1 480
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Мне удалось получить залог, напрямую изменив django-allauth. Поскольку он использует API v1, вам необходимо изменить области действия, чтобы получить информацию из конечных точек API v2. Для этого мне пришлось модифицировать провайдер патреона и просмотры от allauth.

Это всего лишь мой второй проект на питоне, так что извините за возможно беспорядочный или не идеальный код:

провайдер.py

    # Change
    def get_default_scope(self):
        return ['pledges-to-me', 'users', 'my-campaign']

    # to
    def get_default_scope(self):
        return ['identity', 'identity[email]', 'campaigns', 'campaigns.members']

просмотры.py

"""
Views for PatreonProvider
https://www.patreon.com/platform/documentation/oauth
"""

import requests

from allauth.socialaccount.providers.oauth2.views import (
    OAuth2Adapter,
    OAuth2CallbackView,
    OAuth2LoginView,
)

from .provider import PatreonProvider


class PatreonOAuth2Adapter(OAuth2Adapter):
    provider_id = PatreonProvider.id
    access_token_url = 'https://www.patreon.com/api/oauth2/token'
    authorize_url = 'https://www.patreon.com/oauth2/authorize'
    profile_url = 'https://www.patreon.com/api/oauth2/v2/identity?include=memberships&fields[user]=email,first_name,full_name,image_url,last_name,social_connections,thumb_url,url,vanity'


    def complete_login(self, request, app, token, **kwargs):
        resp = requests.get(self.profile_url,
                            headers = {'Authorization': 'Bearer ' + token.token})
        extra_data = resp.json().get('data')

        try:
            member_id = extra_data['relationships']['memberships']['data'][0]['id']
            member_url = f'https://www.patreon.com/api/oauth2/v2/members/{member_id}?include=currently_entitled_tiers&fields%5Btier%5D=title'
            resp_member = requests.get(member_url,
                                headers = {'Authorization': 'Bearer ' + token.token})
            pledge_title = resp_member.json()['included'][0]['attributes']['title']
            extra_data["pledge_level"] = pledge_title

        except (KeyError, IndexError):
            extra_data["pledge_level"] = None
            pass


        return self.get_provider().sociallogin_from_response(request,
                                                             extra_data)


oauth2_login = OAuth2LoginView.adapter_view(PatreonOAuth2Adapter)
oauth2_callback = OAuth2CallbackView.adapter_view(PatreonOAuth2Adapter)

При этом вы можете запросить из конечных точек API v2 (все еще используя клиент APIv1, еще не проверял, работает ли он с клиентом API v2), и он добавит заголовок залога в поле extra_data в социальной учетной записи.

Теоретически вы должны иметь возможность добавить следующее в settings.py, а не редактировать код в provider.py: SOCIALACCOUNT_PROVIDERS = { 'patreon': { 'SCOPE': ['identity', 'identity[email]', 'campaigns', 'campaigns.members'] } }

Rick Westera 18.06.2019 03:48

profile_url выше для меня не работает из-за квадратных скобок. Замена этой строки на profile_url = 'https://www.patreon.com/api/oauth2/v2/identity?include=memb‌​erships&fields%5Buse‌​r%5D=email,first_nam‌​e,full_name,image_ur‌​l,last_name,social_c‌​onnections,thumb_url‌​,url,vanity' работает.

Rick Westera 16.08.2019 06:50

Я обновил django-allauth, используя части ответа Ника С., чтобы включить Patreon API v2 (начиная с django-allauth 0.40.0).

Чтобы использовать API v2, теперь вы можете просто изменить запись патреона для SOCIALACCOUNT_PROVIDERS в settings.py:

settings.py (добавьте в конец)

SOCIALACCOUNT_PROVIDERS = {
    'patreon': {
        'VERSION': 'v2',
    }
}

По умолчанию это также добавит уровень залога в социальную учетную запись каждого пользователя, сохранив его в extra_data['pledge_level'].

Спасибо, чувак, за обновление программного обеспечения (жаль, что я опоздал с этим на 2 года :))

Ondřej Kolín 19.06.2021 20:09

Другие вопросы по теме