我们正在使用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版本一样简单。
答案 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 导致的错误:
('Connection aborted.', error(13, 'Permission denied'))
。('Connection broken: IncompleteRead(80 bytes read)', IncompleteRead(80 bytes read))
也会在稍后出现。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']