Devappserver本地运行报错:Attempted RPC call without active security ticket
问题背景
我们正从webapp2迁移至最新版Django,现阶段需继续使用AppEngine NDB等遗留服务,后续再逐步切换到新技术。由于Devappserver不支持Python3,采用Docker搭建本地开发环境,容器内Google Cloud SDK版本为424.0.0。服务器可正常启动,但访问调用遗留服务(如memcache)的View时,持续报错:google.appengine.runtime.apiproxy_errors.RPCFailedError: Attempted RPC call without active security ticket
部署到AppEngine标准环境运行正常,仅本地Docker环境出现该问题,使用的是Legacy Bundled Services包。
已尝试但无效的操作
- 创建
appengine_config.py - 基于
google.appengine.ext.ndb.django_middleware.NdbDjangoMiddleware适配新版Django中间件 - 通过
gcloud auth激活服务账号并设置项目ID - 配置
GOOGLE_CLOUD_PROJECT环境变量 - 使用旧版Google Cloud SDK 183.0.0单独容器运行Datastore模拟器
解决思路与方案
该错误本质是本地环境缺少AppEngine API代理所需的安全凭证上下文,以下是针对性修复步骤:
1. 启动本地API模拟器并配置连接
在Docker容器内分别启动Datastore和memcache模拟器,同时设置环境变量让应用连接到模拟器:
# 启动Datastore模拟器 gcloud beta emulators datastore start --project=你的项目ID --no-store-on-disk # 设置Datastore连接变量 export DATASTORE_EMULATOR_HOST=localhost:8081 export DATASTORE_PROJECT_ID=你的项目ID # 启动memcache模拟器 gcloud beta emulators memcache start # 设置memcache连接变量 export MEMCACHE_EMULATOR_HOST=localhost:11211
2. 自定义Django中间件初始化AppEngine上下文
在Django项目中添加自定义中间件,确保每个请求都初始化API代理的安全上下文:
# yourapp/middleware.py from google.appengine.api import apiproxy_stub_map from google.appengine.api import user_service_stub from google.appengine.api import memcache from google.appengine.runtime import apiproxy_errors from google.appengine.api import api_proxy, app_identity class AppEngineLegacyContextMiddleware: def __init__(self, get_response): self.get_response = get_response # 注册必要的API存根 if not apiproxy_stub_map.apiproxy.GetStub('user'): apiproxy_stub_map.apiproxy.RegisterStub('user', user_service_stub.UserServiceStub()) if not apiproxy_stub_map.apiproxy.GetStub('memcache'): apiproxy_stub_map.apiproxy.RegisterStub('memcache', memcache.MemcacheServiceStub()) def __call__(self, request): # 确保请求上下文存在有效凭证 try: api_proxy._GetCaller() except AttributeError: api_proxy.SetCaller(app_identity.get_application_id()) response = self.get_response(request) return response
然后在settings.py的MIDDLEWARE列表中添加该中间件(放在靠前位置):
MIDDLEWARE = [ 'yourapp.middleware.AppEngineLegacyContextMiddleware', # 其他中间件... ]
3. 配置应用默认凭证
在Docker容器内执行以下命令设置应用默认凭证,为API调用提供合法上下文:
gcloud auth application-default login
也可将本地的应用默认凭证文件(路径通常为~/.config/gcloud/application_default_credentials.json)挂载到容器内对应路径,避免重复登录。
4. 降级Google Cloud SDK到兼容版本
尝试将容器内的SDK版本降级到300.0.0左右,该版本对Python3和AppEngine遗留服务的API代理逻辑兼容性更稳定,可避免新版本SDK的逻辑变更导致的问题。
内容的提问来源于stack exchange,提问作者hassansuhaib

