我使用python和谷歌应用程序引擎。我想使用任务队列。作为任务队列处理程序的一部分,我检查当前用户是否是管理员(使用Users服务)。这个测试总是失败。有没有办法让这个测试通过?
update:为了避免进一步的混乱,我试图找出触发任务的用户是否是管理员(这只是一个简单的例子)。我知道任务是从服务器上运行的,所有用户的cookie都消失了。所以我想要的答案是将会话转移到任务
import logging
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import taskqueue
class MyRequesHandler(webapp.RequestHandler):
def get(self):
taskqueue.add(url="/task/")
class MyTaskHandler(webapp.RequestHandler):
def post(self):
if users.is_current_user_admin():
logging.debug("admin")
else:
logging.debug("not admin")
def main():
logging.getLogger().setLevel(logging.DEBUG)
application = webapp.WSGIApplication([
('/', MyRequesHandler),
('/task/', MyTaskHandler)
],
debug=True)
run_wsgi_app(application)
Users API反映了当前请求的登录用户的详细信息,显然在任务队列任务的情况下,没有用户,因为它是由任务队列系统发起的。您需要在进入任务队列之前执行此检查,并将结果作为标志传递给任务。
要让任务代表某些特定对象执行,只需将数据存储ID或键(或任何其他用户标识符)传输给任务作为其有效负载。
class MyRequesHandler(webapp.RequestHandler):
def get(self):
taskqueue.add(url="/task/do_something", params={'user_email': users.get_current_user().email()})
class MyTaskHandler(webapp.RequestHandler):
def post(self):
user_email = self.request.POST.get('user_email')
user = User.all().filter('email', user_email).get()
# ... do something on behalf of user
这显然需要保护任务的URL免受外部未经授权的访问——这可以在app.yaml
:
handlers:
- url: /task/(.*)
script: tasks.py
login: admin
Taskqueue访问需要admin登录的url没有问题
执行任务队列项时,原始用户无法通过users服务访问。但是,在创建任务时,您可以将原始用户的ID作为请求的一部分。
要防止外部用户在任务执行期间伪造此用户ID,请查找X-AppEngine-QueueName
请求头。