【问题标题】:Fetch firebase user info from AppEngine application从 AppEngine 应用程序中获取 firebase 用户信息
【发布时间】:2018-09-03 12:07:07
【问题描述】:

我们正在使用 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 (在 Mac 上)的 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

更新 1 个结果:

生成的新错误:

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

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

任何人都使用 GAE 成功实施了 Firebase 身份验证?这感觉有点像掉进兔子洞,认为使用 SDK 就像使用 javascript 版本的 firebase auth 一样简单。

【问题讨论】:

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


    【解决方案1】:

    如果您使用的是 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查看更多信息

    【讨论】:

    • 我阅读了提供的链接,但我不确定如果 GAE 已经支持 HTTPS 并且可以通过 LetsEncrypt 颁发证书,为什么还需要 SSL 库。此外,添加- name: ssl version: latest 会引入一个新错误: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 你会知道为什么首先需要所有这些吗?有没有解决的办法?我们处理的其他 API 不需要这些!
    • I am not sure why SSL library is required if GAE already supports HTTPS and certificates can be issued for example via LetsEncrypt - AppEngine 的前端负责 https 证书,而不是您的应用程序。为了让您的应用能够创建和处理传出的 https 连接,需要一个 ssl 库,其中大多数(全部?)都是用 C 编写的,这意味着您不能简单地将它们包含在您的应用中(因为只允许使用纯 python 模块)所以谷歌提出了一小部分列入白名单的 C 库,可以通过app.yamllibraries 部分包含。
    【解决方案2】:

    更新 2 和分辨率

    根据 update 1 发现的错误:

    1. 页面TransportError when running within App Engine提到了一个 相同错误的解决方法('Connection aborted.', error(13, 'Permission denied'))
    2. 还有这个stack overflow answer 错误('Connection broken: IncompleteRead(80 bytes read)', IncompleteRead(80 bytes read)) 也出现在后面。

    来自 Mihail 和上述页面的回答终于使使用 firebase auth 从 Firebase Auth Users 获取用户成为可能

    作为参考,最终的代码 sn-ps 将是:

    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']
    

    【讨论】:

      猜你喜欢
      • 2019-06-27
      • 2016-09-27
      • 1970-01-01
      • 2011-09-17
      • 2017-04-06
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多