从AppEngine应用程序

时间:2018-03-25 05:50:58

标签: python-2.7 firebase google-app-engine firebase-authentication webapp2

我们正在使用Firebase身份验证进行测试,我们正在检查python SDK。 尝试从Firebase用户进行简单的获取用户操作会导致以下错误:

TransportError: HTTPSConnectionPool(host='accounts.google.com', port=443): Max retries exceeded with url: /o/oauth2/token (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.",))

我们从本地服务器测试然后从暂存GAE URL进行测试,因为我们最初的想法是可能与Firebase 通信需要请求来自Https URL。但是,在这两种情况下,我们都看到了同样的错误。那可能是别的了。

使用的代码提取:

import firebase_admin
from firebase_admin import auth
from firebase_admin import credentials

cred = credentials.Certificate("custom/conf/conf.json")
default_app = firebase_admin.initialize_app(cred)

user_uid = '901234753'
user = auth.get_user(user_uid)
print 'Successfully fetched user data: {0}'.format(user.uid)

有什么线索可能导致此错误以及如何解决?

更新1:

按照@Mihail Russu的评论

在app.yaml中添加SSL
- name: ssl
version: latest

生成了一个新错误:ImportError: cannot import name RAND_egd

排队:

from _ssl import RAND_add, RAND_egd, RAND_status, SSL_ERROR_ZERO_RETURN, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE,,SSL_ERROR_INVALID_ERROR_CODE

根据页面"ImportError: cannot import name RAND_egd "和页面"Fix RAND_egd import error in SDK...",我编辑了位于/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine的socket.py(在Mac上)以匹配他们的建议:

from _ssl import \
    RAND_add, \
    RAND_status, \
    SSL_ERROR_ZERO_RETURN, \
    SSL_ERROR_WANT_READ, \
    SSL_ERROR_WANT_WRITE, \
    SSL_ERROR_WANT_X509_LOOKUP, \
    SSL_ERROR_SYSCALL, \
    SSL_ERROR_SSL, \
    SSL_ERROR_WANT_CONNECT, \
    SSL_ERROR_EOF, \
    SSL_ERROR_INVALID_ERROR_CODE
try:
    from _ssl import RAND_egd
except ImportError:
    # LibreSSL does not provide RAND_egd
    pass

更新1结果:

生成新错误:

- >本地开发服务器:('Connection aborted.', error(13, 'Permission denied'))

- > GAE:('Connection broken: IncompleteRead(100 bytes read)', IncompleteRead(100 bytes read))

任何人都使用GAE成功实施了Firebase Auth?这感觉有点像走下兔子洞,想到使用SDK会像firebase auth的javascript版本一样简单。

2 个答案:

答案 0 :(得分:2)

如果您使用的是AppEngine标准环境,请确保app.yaml中包含以下内容:

libraries:
- name: ssl
  version: latest
  

App Engine通过SSL库支持Python 2.7运行时的本机Python SSL库,必须添加到您的应用

https://cloud.google.com/appengine/docs/standard/python/sockets/ssl_support

了解详情

答案 1 :(得分:0)

更新2&分辨率

发现更新1 导致的错误:

  1. 提到的页面TransportError when running within App Engine 针对相同错误('Connection aborted.', error(13, 'Permission denied'))
  2. 的解决方法
  3. 这是stack overflow answer 错误('Connection broken: IncompleteRead(80 bytes read)', IncompleteRead(80 bytes read))也会在稍后出现。
  4. Mihail和上述网页的回答终于使用firebase auth来获取用户表单Firebase Auth用户

    作为参考,最终的代码片段是:

    app.yaml:

    - name: ssl
      version: latest
    

    appengine_config.py:

    # appengine_config.py
    import os
    import google
    import imp
    import inspect
    
    from google.appengine.ext import vendor
    
    # Add any libraries install in the "lib" folder.
    vendor.add('lib')
    
    # whitelists the socket and ssl libraries for the dev app server, and uses the system-level socket library instead of the one packaged with the App Engine SDK. Your mileage may vary.    
    if os.environ.get('SERVER_SOFTWARE', '').startswith('Development'):
        from google.appengine.tools.devappserver2.python import sandbox
        sandbox._WHITE_LIST_C_MODULES += ['_ssl', '_socket']
    
        runtime_path = os.path.realpath(inspect.getsourcefile(inspect))
        runtime_dir = os.path.dirname(runtime_path)
    
        # Patch and reload the socket module implementation.
        system_socket = os.path.join(runtime_dir, 'socket.py')
        imp.load_source('socket', system_socket)
    
        # Patch and reload the ssl module implementation.
        system_ssl = os.path.join(runtime_dir, 'ssl.py')
        imp.load_source('ssl', system_ssl)
    

    socket.py:

    from _ssl import \
        RAND_add, \
        RAND_status, \
        SSL_ERROR_ZERO_RETURN, \
        SSL_ERROR_WANT_READ, \
        SSL_ERROR_WANT_WRITE, \
        SSL_ERROR_WANT_X509_LOOKUP, \
        SSL_ERROR_SYSCALL, \
        SSL_ERROR_SSL, \
        SSL_ERROR_WANT_CONNECT, \
        SSL_ERROR_EOF, \
        SSL_ERROR_INVALID_ERROR_CODE
    try:
        from _ssl import RAND_egd
    except ImportError:
        # LibreSSL does not provide RAND_egd
        pass
    

    代码:

    # firebase
    import firebase_admin
    from firebase_admin import auth
    from firebase_admin import credentials
    
    # handle requests for GAE
    import requests
    import requests_toolbelt.adapters.appengine
    
    requests_toolbelt.adapters.appengine.monkeypatch()
    
    # initialize firebase
    cred = credentials.Certificate("custom/conf/conf.json")
    default_app = firebase_admin.initialize_app(cred)
    
    user_uid = '901234753'
    user = auth.get_user(user_uid)
    print 'Successfully fetched user data: {0}'.format(user.uid)
    

    虽然我需要稍后退房,但我确实收到了一些警告:

    AppEnginePlatformWarning: urllib3 is using URLFetch on Google App 
    Engine sandbox instead of sockets. To use sockets directly instead of 
    URLFetch see https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.AppEnginePlatformWarning)
    
    WARNING  2018-03-26 00:33:31,894 urlfetch_stub.py:534] Stripped prohibited headers from URLFetch request: ['Content-Length']
    WARNING  2018-03-26 00:33:33,079 urlfetch_stub.py:534] Stripped prohibited headers from URLFetch request: ['Content-Length']