Проблема с аутентификацией токена JWT в PyGithub

Я хочу создать приложение github на python, и я застрял в части аутентификации. Поскольку по умолчанию они не поддерживают python, мне приходится использовать стороннюю библиотеку. После создания токена JWT я могу успешно пройти аутентификацию с помощью curl, но не с библиотекой.

Я пытался использовать PyGithub и Github.py, и оба вернули ошибку «Неверные учетные данные», поэтому я, должно быть, что-то упустил.

import jwt
from github import Github
from dotenv import load_dotenv


load_dotenv()
GITHUB_PRIVATE_KEY = os.getenv('GITHUB_PRIVATE_KEY')
GITHUB_APP_IDENTIFIER = os.getenv('GITHUB_APP_IDENTIFIER')
GITHUB_WEBHOOK_SECRET = os.getenv('GITHUB_WEBHOOK_SECRET')

message = {'iat': int(time.time()),
           'exp': int(time.time()) + (10 * 60),
           'iss': GITHUB_APP_IDENTIFIER}

token = jwt.encode(message, GITHUB_PRIVATE_KEY.strip().encode(), 'RS256')

gh = Github(jwt=token.decode())

for repo in gh.get_user().get_repos():
    print(repo.name)

Эта команда curl возвращает данные моего приложения:

curl -i -H "Authorization: Bearer YOUR_JWT" -H "Accept: application/vnd.github.machine-man-preview+json" https://api.github.com/app

Я ожидаю, что код будет аутентифицировать и распечатывать мои репозитории, однако я получаю

Traceback (most recent call last):
  File "C:/python/jeev/testing.py", line 21, in <module>
    for repo in gh.get_user().get_repos():
  File "C:/python/jeev\venv\lib\site-packages\github\PaginatedList.py", line 62, in __iter__
    newElements = self._grow()
  File "C:/python/jeev\venv\lib\site-packages\github\PaginatedList.py", line 74, in _grow
    newElements = self._fetchNextPage()
  File "C:/python/jeev\venv\lib\site-packages\github\PaginatedList.py", line 199, in _fetchNextPage
    headers=self.__headers
  File "C:/python/jeev\venv\lib\site-packages\github\Requester.py", line 276, in requestJsonAndCheck
    return self.__check(*self.requestJson(verb, url, parameters, headers, input, self.__customConnection(url)))
  File "C:/python/jeev\venv\lib\site-packages\github\Requester.py", line 287, in __check
    raise self.__createException(status, responseHeaders, output)
github.GithubException.BadCredentialsException: 401 {'message': 'Bad credentials', 'documentation_url': 'https://developer.github.com/v3'}

Версия Github3.py:

import jwt
import github3
from dotenv import load_dotenv


load_dotenv()
GITHUB_PRIVATE_KEY = os.getenv('GITHUB_PRIVATE_KEY')
GITHUB_APP_IDENTIFIER = os.getenv('GITHUB_APP_IDENTIFIER')
GITHUB_WEBHOOK_SECRET = os.getenv('GITHUB_WEBHOOK_SECRET')

gh = github3.github.GitHub()
gh.login_as_app(GITHUB_PRIVATE_KEY.encode(), GITHUB_APP_IDENTIFIER)
gh.me()

Возникает то же исключение 401 неверных учетных данных. Я включил печать в функцию login_as_app, поэтому теперь она выводит токен JWT, я использовал его с командой curl и получил то, что хочу. Странный.

Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
5
0
1 075
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Типичный случай RTFM: я должен был аутентифицироваться как установка.

Просто чтобы расширить ответ @ilo, как аутентифицироваться как установка:

import github3

key_file = 'private-key.pem'

GITHUB_PRIVATE_KEY = open(key_file, 'r').read()
GITHUB_APP_IDENTIFIER = "6"

gh = github3.github.GitHub()

# Login as app
gh.login_as_app(GITHUB_PRIVATE_KEY.encode(), GITHUB_APP_IDENTIFIER)

# Login to the installation, assuming only a single one
installations = [installation.id for installation in gh.app_installations()]
gh.login_as_app_installation(GITHUB_PRIVATE_KEY.encode(), GITHUB_APP_IDENTIFIER, installations[0])

# Access information
# e.g. the rate limit
print(gh.rate_limit())
# or access token to checkout the repository
print(gh.session.auth.token)

При наличии нескольких аутентификаций установки можно отфильтровать, сравнив installation.account['login'] с именем организации/пользователя.

С PyGithub вы неправильно использовали API

Это сделает это

from github import Github, GithubIntegration

with open("apps-private-key.pem", "r") as secret:
    private_key = secret.read()

GITHUB_APP_ID = "1234"
integration = GithubIntegration(
    GITHUB_APP_ID, private_key, base_url = "https://github.com/api/v3")

install = integration.get_installation("owner", "repository")
access = integration.get_access_token(install.id)

# And here it is :)
print(access.token)

gh = Github(login_or_token=access.token,
            base_url = "https://github.com/api/v3")

# your operations

Мне потребовалось некоторое время, чтобы понять эту последовательность, в документах PyGithub отсутствуют некоторые биты.

Как выглядит структура вашей переменной private_key? Есть ли в нем части "-----BEGIN PRIVATE KEY-----" / "-----END PRIVATE KEY-----"?

olucafont6 12.01.2022 02:19

Неважно, добавление их в начало и конец ключа, похоже, сработало. Спасибо!

olucafont6 12.01.2022 02:28

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