Настройте Eve-Flask с oAuth поверх heroku

У меня есть API Python (Eve-Flask с oAuth 2.0), который успешно работает на локальном хосте.

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

Здесь у вас есть:

> curl -k -X POST -d "client_id=XXXXX&grant_type=password&username=XXX&password=YYYY" https://MYAPP.herokuapp.com/oauth/token

И ответ API:

> {"access_token": "VWQjYBOMTkeqPbiql8dl2T1fbBM1WH", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "Z0d1O3LUVrE1lIaYuQ3hOkZSFO9GuX", "scope": ""}

До сих пор все правильно, кроме того, я могу получить доступ к некоторой конечной точке с помощью сгенерированного токена:

> curl -k -H "Authorization: Bearer VWQjYBOMTkeqPbiql8dl2T1fbBM1WH" https://MYAPP.herokuapp.com/myendpoint

>You have access the protected resource!

С другой стороны:

curl -k -H "Authorization: Bearer VWQjYBOMTkeqPbiql8dl2T1fbBM1WH" https://MYAPP.herokuapp.com/api_resource


Traceback (most recent call last):
  File "/app/.heroku/python/lib/python2.7/site-packages/eve/flaskapp.py", line 968, in __call__
    return super(Eve, self).__call__(environ, start_response)
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/app/.heroku/python/lib/python2.7/site-packages/eve/endpoints.py", line 54, in collections_endpoint
    response = get(resource, lookup)
  File "/app/.heroku/python/lib/python2.7/site-packages/eve/methods/common.py", line 242, in rate_limited
    return f(*args, **kwargs)
  File "/app/.heroku/python/lib/python2.7/site-packages/eve/auth.py", line 77, in decorated
    if not auth.authorized(roles, resource_name, request.method):
  File "/app/oauth2.py", line 45, in authorized
    return self.check_auth(token, allowed_roles, resource, method)
  File "/app/oauth2.py", line 33, in check_auth
    return token and self.redis.get(token)
  File "/app/.heroku/python/lib/python2.7/site-packages/redis/client.py", line 880, in get
    return self.execute_command('GET', name)
  File "/app/.heroku/python/lib/python2.7/site-packages/redis/client.py", line 578, in execute_command
    connection.send_command(*args)
  File "/app/.heroku/python/lib/python2.7/site-packages/redis/connection.py", line 563, in send_command
    self.send_packed_command(self.pack_command(*args))
  File "/app/.heroku/python/lib/python2.7/site-packages/redis/connection.py", line 538, in send_packed_command
    self.connect()
  File "/app/.heroku/python/lib/python2.7/site-packages/redis/connection.py", line 442, in connect
    raise ConnectionError(self._error_message(e))
ConnectionError: Error 111 connecting to localhost:6379. Connection refused.

фрагмент run.py

app = Eve(auth=BearerAuth)
ResourceOwnerPasswordCredentials(app)

@app.route('/myendpoint')
@oauth.require_oauth()
def restricted_access():
    return "You have access the protected resource!"

if __name__ == '__main__':
    host = str(os.environ.get('HOST', '0.0.0.0'))
    app.run(host, int(os.environ.get('PORT')),debug=True)

Я установил Redis в героку, однако эта ошибка:

ConnectionError: Error 111 connecting to localhost:6379. Connection refused.

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

Заранее спасибо.

Николя


person Nicolas Moraes    schedule 20.12.2016    source источник


Ответы (2)


Наконец, я смог смягчить ошибку redis и запустить API над Heroku, редактируя oauth2.py:

def __init__(self):
        super(BearerAuth, self).__init__()
        self.redis = StrictRedis(host='XXX',port=123,password='YYY')

вместо

self.redis = StrictRedis()

Ваше здоровье.

person Nicolas Moraes    schedule 15.02.2017

Трассировка стека указывает на проблему с подключением к Redis:

 File "/app/.heroku/python/lib/python2.7/site-packages/redis/connection.py", line 442, in connect
raise ConnectionError(self._error_message(e))

Поэтому я бы удостоверился, что Redis запущен и работает на вашем экземпляре. Также убедитесь, что SENTINEL_REDIS_URL установлен на правильный порт (может быть, heroku запускает Redis на нестандартном порту?)

person Nicola Iarocci    schedule 09.02.2017
comment
У меня есть следующее свойство в settings.py: SENTINEL_REDIS_URL = 'redis://rediscloud:[email protected]:12864' и та же ошибка: Ошибка 111 при подключении к локальному хосту: 6379. В соединении отказано. Это может быть попытка подключиться к локальному хосту. - person Nicolas Moraes; 13.02.2017
comment
Наконец, я смог смягчить ошибку redis, добавив переменную REDIS_URL в settings.py REDIS_URL = 'redis://rediscloud:XXXXXXXXXXX/0, однако у меня есть другие ошибки. - person Nicolas Moraes; 15.02.2017