Получение токена

Пример демонстрирует получение OAuth-токенa веб-сервисом. Рекомендации для других типов приложений (настольное, мобильное) приведены в документации Яндекс.OAuth.

Установка дополнительных библиотек

Для установки библиотек (flask, requests, suds, pyxb и др.) можно использовать утилиту pip:
pip install %package_name%

Утилита pip включена в Python 2 начиная с версии 2.7.9 и в Python 3 начиная с версии 3.4. Если вы используете более раннюю версию Python, установите pip, например, с помощью скрипта https://bootstrap.pypa.io/get-pip.py.

Более подробную информацию вы можете найти на странице https://packaging.python.org/tutorials/installing-packages/.

Callback URL

При регистрации или редактировании параметров приложения на сервисе Яндекс.OAuth необходимо в поле Callback URL указать URL скрипта, выполняющего получение токена. Например:

 https://site.ru/get_token

Последовательность действий

При запросе токена требуется указывать идентификатор и пароль приложения, сгенерированные при регистрации на сервисе Яндекс.OAuth.

  1. Приложение направляет пользователя на страницу запроса доступа по ссылке вида
    https://oauth.yandex.ru/authorize?response_type=code&client_id=ИДЕНТИФИКАТОР_ПРИЛОЖЕНИЯ

    На открывшейся странице пользователь нажимает кнопку Разрешить.

  2. Яндекс.OAuth осуществляет редирект на адрес из Callback URL. При этом к адресу добавляется параметр code. Например:
     http://site.ru/get_token?code=КОД_ПОДТВЕРЖДЕНИЯ
  3. Скрипт выполняет POST-запрос на https://oauth.yandex.ru/token, передавая следующие параметры:
    • grant_type = authorization_code

    • code = КОД_ПОДТВЕРЖДЕНИЯ

    • client_id = ИДЕНТИФИКАТОР_ПРИЛОЖЕНИЯ

    • client_secret = ПАРОЛЬ ПРИЛОЖЕНИЯ

  4. Яндекс.OAuth передает ответ в формате JSON. Ключ access_token содержит OAuth-токен. Например:
    {"access_token": "0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"}

    Полученный токен необходимо сохранить и использовать в запросах к API Директа.

Запуск скрипта

Flask позволяет указать только IP-адрес и порт, на котором запускается скрипт. Существует несколько вариантов запуска скрипта:

  • Запустите приложение на публичном (то есть видимом из интернета) IP-адресе. Для вашего домена в DNS должен быть указан именно этот IP-адрес, а приложение должно быть запущено на корректном порту (443 для HTTPS).

  • Используйте веб-сервер для проксирования запросов. Например, Nginx в следующей конфигурации:

    server {
        listen 443;
    
        # Укажите домен из поля Callback URL
        server_name site.ru;
    
        access_log  /var/log/nginx/access.log;
        error_log  /var/log/nginx/error.log;
    
        location /get_token {
            proxy_pass         http://127.0.0.1:8000/;
            proxy_redirect     off;
    
            proxy_set_header   Host                 $host;
            proxy_set_header   X-Real-IP            $remote_addr;
            proxy_set_header   X-Forwarded-For     $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto    $scheme;
        }
    }

    В приведенном ниже коде скрипта указаны параметры запуска, соответствующие этой конфигурации.

Более подробную информацию вы можете найти на странице http://flask.pocoo.org/docs/0.12/deploying/.

Код скрипта

Для использования примера укажите идентификатор и пароль приложения.

# -*- coding: utf-8 -*-
from flask import Flask, request, jsonify, redirect
from requests import post

# Метод для кодирования URL как в Python 3, так и в Python 2
import sys

if sys.version_info < (3, 0):  # Pytohn2.x
    from urllib import urlencode
else:  # Python3.x
    from urllib.parse import urlencode

# Идентификатор приложения
client_id = 'ИДЕНТИФИКАТОР_ПРИЛОЖЕНИЯ'
# Пароль приложения
client_secret = 'ПАРОЛЬ_ПРИЛОЖЕНИЯ'
# Адрес сервера Яндекс.OAuth
baseurl = 'https://oauth.yandex.ru/'

app = Flask(__name__)


@app.route('/')
def index():
    if request.args.get('code', False):
        # Если скрипт был вызван с указанием параметра "code" в URL,
        # то выполняется запрос на получение токена
        print(request.args)
        print(request.data)
        data = {
            'grant_type': 'authorization_code',
            'code': request.args.get('code'),
            'client_id': client_id,
            'client_secret': client_secret
        }
        data = urlencode(data)
        # Токен необходимо сохранить для использования в запросах к API Директа
        return jsonify(post(baseurl + "token", data).json())
    else:
        # Если скрипт был вызван без указания параметра "code",
        # то пользователь перенаправляется на страницу запроса доступа
        return redirect(baseurl + "authorize?response_type=code&client_id={}".format(client_id))


if __name__ == '__main__':
    # Отладочная информация
    # app.debug = True
    # Запуск веб-сервера с доступом по порту 8000
    app.run(host='127.0.0.1', port=8000)