Каков правильный механизм аутентификации в Google в автономном скрипте Python?

У меня есть код, который я использую для извлечения адреса электронной почты из контактов Gmail в текстовый файл. Это простой скрипт Python, который запускается в задании cron и основан на библиотеке gdata Python (в настоящее время версии 2.0.18).

По сравнению с предыдущим месяцем, это больше не работает из-за того, что Google отказывается от протокола ClientLogin . Полученная ошибка выглядит так:

{'status': 401, 'body': '<?xml version="1.0" encoding="UTF-8"?>\n<errors xmlns="http://schemas.google.com/g/2005">\n <error>\n <domain>GData</domain>\n <code>required</code>\n <location type="header">Authorization</location>\n <internalReason>Login Required</internalReason>\n </error>\n</errors>\n', 'reason': 'Unauthorized'} 

Я знал, что это происходит и обрабатывается в других местах (например, приложения AppEngine), но забыл, что мне придется преобразовать этот скрипт. Теперь, когда я здесь, я обнаружил, что понятия не имею, как я должен выполнять эту работу.

Все ссылки, которые я нашел, например, здесь, в блоге разработчиков Google Apps или здесь и здесь, в StackOverflow, предполагают, что решение должно использовать OAuth2Token. Однако для этого требуется идентификатор клиента и клиентский секрет с консоли Google API, которая привязана к приложению. У меня нет приложения. Я просто хочу аутентифицироваться из своего сценария.

Может кто-нибудь, пожалуйста, предложите правильный способ сделать это в автономном скрипте? Или мне не повезло, и нет никакого механизма для этого?

Это мужество существующего кода контактов:

 from gdata.contacts.service import ContactsService, ContactsQuery user = "myuser@gmail.com" password = "mypassword" addresses = set() client = ContactsService(additional_headers={"GData-Version":"2"}) client.ssl = True client.ClientLogin(user, password) groups = client.GetGroupsFeed() for group in groups.entry: if group.content.text == "System Group: My Contacts": query = ContactsQuery() query.max_results = 9999 # large enough that we'll get "everything" query.group = group.id.text contacts = client.GetContactsFeed(query.ToUri()) for contact in contacts.entry: for email in contact.email: addresses.add(email.address.lower()) break return addresses 

В идеале я хочу заменить client.ClientLogin() другим механизмом, который сохраняет остальную часть кода с помощью gdata. Альтернативно, если это невозможно сделать с gdata, я открыт для преобразования в другую библиотеку, которая предлагает аналогичную функциональность.

2 Solutions collect form web for “Каков правильный механизм аутентификации в Google в автономном скрипте Python?”

Может кто-нибудь, пожалуйста, предложите правильный способ сделать это в автономном скрипте? Или мне не повезло, и нет никакого механизма для этого?

Механизм больше не похож на тот, который вы используете. Вам нужно будет создать проект Cloud Developer и использовать OAuth2 и переписать сценарий.

Чтобы сделать это как можно более надежным, вы можете переключиться на новейший API контактов . С помощью этого API вы можете использовать поток устройства OAuth2 , который может быть проще для вашего варианта использования.

Не тот ответ, который вы надеялись услышать, я знаю, но я думаю, что это единственный ответ.

В итоге оказалось проще просто взломать скрипт оболочки, используя завиток, чем беспорядок с библиотекой gdata. Как и ожидалось, я смог выполнить большую часть процесса проверки вручную, вне сценария, в соответствии с инструкциями потока устройства OAuth2 .

После завершения процесса проверки у меня было 4 требуемых мандата: идентификатор клиента, секрет клиента, токен доступа и токен обновления. По документации Google, токен доступа в конце концов истекает. Вы можете получить новый токен доступа, попросив диспетчера токенов обновить токен. Когда вы это делаете, вы, видимо, получаете новый токен доступа, но не новый токен обновления.

Я храню идентификатор клиента и секрет и токен обновления в файле CREDENTIALS в формате JSON. Поскольку токен доступа изменяется со временем, он сохраняется в файле ACCESS , также в формате JSON.

Важные части сценария показаны ниже:

 #!/bin/ksh CLIENT_ID=$(cat ${CREDENTIALS} | jq -r ".client_id") CLIENT_SECRET=$(cat ${CREDENTIALS} | jq -r ".client_secret") REFRESH_TOKEN=$(cat ${CREDENTIALS} | jq -r ".refresh_token") ACCESS_TOKEN=$(cat ${ACCESS} | jq -r ".access_token") CONTACTS_URL="https://www.google.com/m8/feeds/contacts/default/full?access_token=${ACCESS_TOKEN}&max-results=5000&v=3.0" ERROR=$(curl --show-error --silent --fail "${CONTACTS_URL}" -o ${CONTACTS_XML} 2>&1) RESULT=$? if [[ ${RESULT} -eq 0 ]] then cat ${CONTACTS_XML} | grep 'gd:email' | sed 's/^.*address="//g' | sed 's/".*$//g' | tr '[:upper:]' '[:lower:]' | sort | uniq elif [[ ${RESULT} -eq 22 ]] then echo "${ERROR}" | grep -q "401" if [[ $? -eq 0 ]] then TOKEN_URL="https://www.googleapis.com/oauth2/v3/token" REFRESH_PARAMS="client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&refresh_token=${REFRESH_TOKEN}&grant_type=refresh_token" ERROR=$(curl --show-error --silent --fail --data "${REFRESH_PARAMS}" ${TOKEN_URL} -o ${REFRESH_JSON}) RESULT=$? if [[ ${RESULT} -eq 0 ]] then ACCESS_TOKEN=$(cat ${REFRESH_JSON} | jq -r ".access_token") jq -n --arg access_token "${ACCESS_TOKEN}" '{"access_token": $access_token, }' > ${ACCESS} CONTACTS_URL="https://www.google.com/m8/feeds/contacts/default/full?access_token=${ACCESS_TOKEN}&max-results=5000&v=3.0" ERROR=$(curl --show-error --silent --fail "${CONTACTS_URL}" -o ${CONTACTS_XML} 2>&1) RESULT=$? if [[ ${RESULT} -eq 0 ]] then cat ${CONTACTS_XML} | grep 'gd:email' | sed 's/^.*address="//g' | sed 's/".*$//g' | tr '[:upper:]' '[:lower:]' | sort | uniq else print "Unexpected error: ${ERROR}" >&2 exit 1 fi else print "Unexpected error: ${ERROR}" >&2 exit 1 fi else print "Unexpected error: ${ERROR}" >&2 exit 1 fi else print "Unexpected error: ${ERROR}" >&2 exit 1 fi 

Это не самая красивая вещь в мире, но я искал что-то быстро-грязное, и это работает.

  • Создать долгоживущий токен доступа из недолговечного?
  • Python - как пройти проверку подлинности с помощью Google Analytics от AWS Lambda?
  • Как аутентифицировать себя как API для Google Диска?
  •  
    Interesting Posts for Van-Lav

    Тестирование на 400 ошибок с вставкой в ​​приложении web.py

    TA-Lib numpy "AssertionError: реальный не двойной"

    Нечетные простые множители больших чисел

    Как настроить инструмент setup.py для использования колесных пакетов

    Может ли Python генерировать случайное число, исключающее набор чисел без использования рекурсии?

    Импорт Python для тестирования с использованием носа – что лучше всего подходит для импорта модулей выше текущего пакета

    алгоритм сокращения минимума karger в python 2.7

    Статические файлы в приложении «Бутылка» не найдены (404)

    Как редактировать несколько элементов в df.columns

    Исключение кавычек для MySQL в python

    Python-Создание объекта Class-x не имеет атрибута 'split'

    Получение модуля python -m для работы с модулем, реализованным на C

    Использование функции startswith () внутри списков в python

    TNonblockingServer в аварийных ситуациях, когда открывается TFramedTransport

    Каждый день, неделю, месяц, год в AppEngine cron (python)

    Python - лучший язык программирования в мире.