2016-12-22 2 views
5

Укажите нужный документ, учебник, например, или укажите его, указав, как добавить определенный токен аутентификации в определенный заголовок в Swagger создал API-клиент в Python?Особенности добавления заголовка к вызову api с клиентом swagger codegen в python неясны

Вот что я пробовал:
Мой API вызова работает просто отлично с правой завитка команды:

curl -v -H 'X-CAG-Authorization: AG_CONSUMER_TOKEN access-key=31337-70k3n' \ 
    'https://api.company.net/api/v1/user/detail?user=1' 

* Trying 10.10.1.10... 
* Connected to api.company.net (10.10.1.10) port 443 (#0) 
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 
* Server certificate: *.company.net 
* Server certificate: COMODO RSA Organization Validation Secure Server CA 
* Server certificate: COMODO RSA Certification Authority 
> GET /api/v1/user/detail?user=1 HTTP/1.1 
> Host: api.company.net 
> User-Agent: curl/7.49.1 
> Accept: */* 
> X-CAG-Authorization: AG_CONSUMER_TOKEN access-key=31337-70k3n 
> 
< HTTP/1.1 200 OK 
< Server: openresty 
< Date: Thu, 22 Dec 2016 19:46:05 GMT 
< Content-Type: application/json;charset=UTF-8 
< Transfer-Encoding: chunked 
< Connection: close 
< Vary: Accept-Encoding 
< Vary: Accept-Encoding 
< X-UA-Compatible: IE=edge 
< 
{"successful":true,"message":"SUCCESS","body":{"… 

Однако, когда я пытаюсь тот же базовый запрос в моей (2.7.12) клиент Python Я получаю сбой авторизации, несмотря на то, что токен вводит его в заголовок, который будет использоваться. Более подробная информация о правильном способе использования клиента или о том, как получить более подробную информацию о точном запросе и ответе, будет оценена по достоинству.

/Users/me/VEnvs/sku-grade/bin/python /Users/me/prj/code/python_client/api_example.py 
HEADERS: 
{'X-CAG-Authorization': 'AG_CONSUMER_TOKEN access-key=31337-70k3n', 'User-Agent': 'Swagger-Codegen/1.0.0/python'} 
Exception when calling SupplierApi->get_api_v1_user_details: (401) 
Reason: Unauthorized 
HTTP response headers: HTTPHeaderDict({'Date': 'Thu, 22 Dec 2016 21:09:30 GMT', 'Content-Length': '636', 'Content-Type': 'application/json; charset=UTF-8', 'Connection': 'keep-alive', 'Server': 'nginx'}) 
HTTP response body: { 
    "code" : "PRECONDITION_FAILED", 
    "type" : "UnauthorizedApiDeniedException", 
    "message" : "Target API(/api/v1/user/details) is not available, you have to get a grant in advance.", 
    "messages" : {… 

Вот чванство API Spec: swagger.yaml

--- 
swagger: "2.0" 
info: 
    description: "API" 
    version: "TEMPORARY" 
    title: "User Details" 
    termsOfService: "http://wiki.company.net/tos" 
    contact: 
    name: "…" 
    license: 
    name: "…" 
host: "api.company.net" 
basePath: "/api/v1" 
tags: 
- name: "supplier" 
    description: "Supplier" 
schemes: 
- "https" 
produces: 
- "application/json" 
paths: 
    /user/details: 
    get: 
     tags: 
     - "supplier" 
     summary: "userDetails" 
     operationId: "getApiV1UserDetails" 
     consumes: 
     - "application/json" 
     produces: 
     - "application/json;charset=utf-8" 
     parameters: 
     - name: "user" 
     in: "query" 
     description: "user id" 
     required: true 
     type: "integer" 
     format: "Long" 
     responses: 
     200: 
      description: "OK" 
      schema: 
      $ref: "#/definitions/SupplierResponseOfUserDetailsDto" 
     401: 
      description: "Unauthorized" 
     403: 
      description: "Forbidden" 
     404: 
      description: "Not Found" 
definitions: 
    SupplierResponseOfUserDetailsDto: 
    type: "object" 
    properties: 
     body: 
     $ref: "#/definitions/UserDetailsDto" 
     message: 
     type: "string" 
     successful: 
     type: "boolean" 
    UserDetailsDto: 
    type: "object" 
    properties: 
     name: 
     type: "string" 

чванства-Codegen был запущен из http://editor.swagger.io/, и я последовал примеру апи пытается добавить в дополнительный заголовок: api_example.py

from __future__ import print_function 
import time 
import swagger_client 
from swagger_client import ApiClient 
from swagger_client import Configuration 
from swagger_client.rest import ApiException 
from pprint import pprint 

# Setup the authentication token header 
conf = Configuration() 
conf.api_key_prefix = {"teamname": "AG_CONSUMER_TOKEN"} 
conf.api_key = { 
    "teamname": "access-key=31337-70k3n" 
} 
conf.api_client = ApiClient(None, "X-CAG-Authorization", 
          conf.get_api_key_with_prefix("teamname")) 

# create an instance of the API class 
api_instance = swagger_client.SupplierApi() 
user = 1 
try: 
    api_response = api_instance.get_api_v1_user_details(user) 
    pprint(api_response) 
except ApiException as e: 
    print("Exception when calling " 
      "SupplierApi->get_api_v1_user_details: %s\n" % e) 

Поместив print(self.api_client.default_headers) в supplier_api.py, я мог видеть, что заголовок действительно был установлен.

{'X-CAG-Authorization': 'AG_CONSUMER_TOKEN access-key=31337-70k3n', 'User-Agent': 'Swagger-Codegen/1.0.0/python'} 

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

Update Я также попытался его определения:

 security: 
     - api_key: [] 
securityDefinitions: 
    api_key: 
    type: "apiKey" 
    name: "X-CAG-Authorization" 
    in: "header" 

, а затем только настройки ключа с:

swagger_client.configuration.api_key['X-CAG-Authorization'] = \ 
    'access-key=31337-70k3n' 
swagger_client.configuration.api_key_prefix['X-CAG-Authorization'] = \ 
    'AG_CONSUMER_TOKEN' 

Но это не изменится, кроме заголовка исчезает из заголовков по умолчанию, которые я печатал.

+0

Я также попытался связать конфигурацию с помощью 'swagger_client.configuration. ...' для 'api_key_prefix'' api_key' и 'api_client', которые работали одинаково с указанным выше; позже я изменил свой spec, включив «securityDefinitions», и упоминание о «безопасности» удалило эти параметры конфигурации и вместо этого установил только имя api_key по имени. Это не повлияло на заголовок и не изменило поведение. – dlamblin

+0

Я также открыл это как проблему с проектом cagegen swagger: https://github.com/swagger-api/swagger-codegen/issues/4456 – dlamblin

ответ

2

Я пробовал ваш пример кода, и похоже, что ваши заголовки фактически переданы серверу.

Вы можете подтвердить это путем добавления print headers к swagger_client/rest.py файла перед этим:

r = self.pool_manager.request(method, url, 
           fields=query_params, 
           preload_content=_preload_content, 
           timeout=timeout, 
           headers=headers) 

Вы уверены, что нет никаких проблем на стороне сервера? Может быть, некоторые заголовки нарушают аутентификацию?

Работает ли следующая команда curl?

curl -v \ 
-H 'X-CAG-Authorization: AG_CONSUMER_TOKEN access-key=31337-70k3n' \ 
-H 'Content-Type: application/json' \ 
-H 'Accept: application/json;charset=utf-8' \ 
-H 'User-Agent: Swagger-Codegen/1.0.0/python' \ 
'https://api.company.net/api/v1/user/detail?user=1' 

Потому что это должно дать вам тот же самый ответ, который вернулся к чванству, что является ошибкой 401. Если это так, вы можете отлаживать оттуда на стороне сервера. Если это не так, я понятия не имею.

+0

Спасибо, инструкция curl со всеми четырьмя заголовками продолжает проходить, поэтому Я собираюсь дважды проверить, что часть https работает на python и что это не путь (кажется, то же самое). Затем попробуйте создать с последним от мастера swagger-codegen. – dlamblin

+0

Благодарим за то, что вы нашли подходящее место для распечатки всех методов, URL, полей и заголовков. Сделав это, я понял, что для api есть два открытых конечных пункта, и только один работал правильно, поэтому теперь я получаю точно такое же и правильное поведение. Больше документации было бы неплохо иметь, но в этом случае это была проблема отладки правильно. – dlamblin

2

В вашей спецификации вам нужно будет описать параметр безопасности (ключ API в вашем случае), подобный этому example, определенный в разделе securityDefinitions спецификации OpenAPI/Swagger.

Тогда в конечной точке, вам нужно будет «применять» определение безопасности, подобное этому example

После этого, вы можете установить ключ API в configuration.py клиента API Python автоматически генерируемые и запрос HTTP будет соответственно включать в себя ключ API (либо в строке заголовка, либо в строке запроса URL-адреса, как определено в настройке безопасности спецификации).

Со времени последнего стабильного выпуска Swagger Codegen было сделано довольно много улучшений для авто- сгенерированный клиент API Python, поэтому я предлагаю вам вытащить последнего мастера и создать JAR локально для создания клиентов API.

+0

Это полезная дополнительная информация. В своем обновлении я заметил, что обновил спецификацию в обоих примерах. Я не изменял config.py, потому что я не хочу фиксировать ключ в коде; оператор, о котором идет речь, получает его от соединения в воздушном потоке. Но при тестировании я использовал API напрямую, поэтому я тоже попробую. Я также могу попробовать последнюю версию от мастера (я ожидал, что editor.swagger.io будет обновлен). – dlamblin

Смежные вопросы