在 google 应用引擎中创建受限页面
Creating restricted pages in google app engine
我在 Python Google App Engine 网站上创建管理页面时遇到问题。我认为答案应该很简单,但老实说,我一直在努力理解 类 如何从其他 类 继承,或者使用函数来包装其他函数,但我似乎无法理解很好地理解它。
基本上,我的网站有两种页面:主页,然后是一些允许用户执行管理操作的页面。任何人都可以在不登录的情况下看到主页。其他页面供管理员使用。唯一拥有帐户的用户是管理员,所以我设置了 webapp2 会话,只要
self.sessions.get('username')
returns 足以允许访问其他页面的内容。
这是我的处理程序:
class BaseHandler(webapp2.RequestHandler):
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render(self, template, **kw):
self.response.out.write(render_str(template, **kw))
def dispatch(self):
# Get a session store for this request.
self.session_store = sessions.get_store(request=self.request)
try:
# Dispatch the request.
webapp2.RequestHandler.dispatch(self)
finally:
# Save all sessions.
self.session_store.save_sessions(self.response)
@webapp2.cached_property
def session(self):
# Returns a session using the default cookie key.
return self.session_store.get_session()
class MainHandler(BaseHandler):
def get(self):
animals = Animal.query().fetch(100)
self.render('index.html',animals=animals)
class AdminHandler(BaseHandler):
def get(self):
if self.session.get('username'):
self.render('admin.html')
else:
self.render('signin.html')
class ReorderHandler(BaseHandler):
def get(self):
self.render('reorder.html')
def post(self):
#Change order of item display
self.write('OK')
class DeleteHandler(BaseHandler):
def get(self):
self.render('delete.html')
def post(self):
#Delete entry from db
self.write('OK')
class AddHandler(BaseHandler):
def get(self):
self.render('add.html')
def post(self):
#add entry to db
self.write('OK')
class SigninHandler(BaseHandler):
def post(self):
#Check username and password
if valid:
self.session['username'] = username
self.redirect('/admin')
else:
self.write('Not valid')
AdminHandler 列出了这些管理页面应该做什么的基本逻辑。
如果有人试图访问管理页面,处理程序应检查用户是否已登录,如果是,则允许访问该页面。如果没有,它会呈现登录页面。
重新排序、删除和添加都是我希望管理员能够执行的操作,但将来可能会有更多操作。我可以将 AdminHandler 逻辑添加到那些其他处理程序的所有 GET 和 POST,但这是非常重复的,因此我确信这是错误的做法。
正在寻找有关如何将 AdminHandler 的逻辑纳入涵盖 "administrative" 任务的所有其他处理程序的一些指导。
更新: Brent Washburne 为我指明了正确的方向,足以使它正常工作,尽管我仍然觉得我不了解装饰器函数的实际作用。无论如何,代码似乎可以正常工作,现在看起来像这样:
def require_user(old_func):
def new_function(self):
if not self.session.get('username'):
self.redirect('/signin')
old_func(self)
return new_function
class AdminHandler(BaseHandler):
@require_user
def get(self):
self.render('admin.html')
class AddHandler(BaseHandler):
@require_user
def get(self):
self.render('add.html')
@require_user
def post(self):
name = self.request.get('name')
qry = Animal.query(Animal.name == name).get()
if not qry:
new_animal = Animal(name=name)
new_animal.put()
self.write('OK')
所有其他 "admin" 处理程序依此类推。
这是一种确保用户在每个页面(登录页面除外)都登录的蛮力方法,或者将用户重定向到登录页面:
def dispatch(self):
# Get a session store for this request.
self.session_store = sessions.get_store(request=self.request)
if not self.session['username'] and self.request.get('path') != '/login':
return redirect('/login')
更好的方法是将此代码添加到每个 get() 和 put() 例程的顶部:
def get(self):
if not self.session['username']:
return redirect('/login')
更好的方法是将该代码变成装饰器,这样您只需添加一行:
@require_login
def get(self):
....
我在 Python Google App Engine 网站上创建管理页面时遇到问题。我认为答案应该很简单,但老实说,我一直在努力理解 类 如何从其他 类 继承,或者使用函数来包装其他函数,但我似乎无法理解很好地理解它。
基本上,我的网站有两种页面:主页,然后是一些允许用户执行管理操作的页面。任何人都可以在不登录的情况下看到主页。其他页面供管理员使用。唯一拥有帐户的用户是管理员,所以我设置了 webapp2 会话,只要
self.sessions.get('username')
returns 足以允许访问其他页面的内容。
这是我的处理程序:
class BaseHandler(webapp2.RequestHandler):
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render(self, template, **kw):
self.response.out.write(render_str(template, **kw))
def dispatch(self):
# Get a session store for this request.
self.session_store = sessions.get_store(request=self.request)
try:
# Dispatch the request.
webapp2.RequestHandler.dispatch(self)
finally:
# Save all sessions.
self.session_store.save_sessions(self.response)
@webapp2.cached_property
def session(self):
# Returns a session using the default cookie key.
return self.session_store.get_session()
class MainHandler(BaseHandler):
def get(self):
animals = Animal.query().fetch(100)
self.render('index.html',animals=animals)
class AdminHandler(BaseHandler):
def get(self):
if self.session.get('username'):
self.render('admin.html')
else:
self.render('signin.html')
class ReorderHandler(BaseHandler):
def get(self):
self.render('reorder.html')
def post(self):
#Change order of item display
self.write('OK')
class DeleteHandler(BaseHandler):
def get(self):
self.render('delete.html')
def post(self):
#Delete entry from db
self.write('OK')
class AddHandler(BaseHandler):
def get(self):
self.render('add.html')
def post(self):
#add entry to db
self.write('OK')
class SigninHandler(BaseHandler):
def post(self):
#Check username and password
if valid:
self.session['username'] = username
self.redirect('/admin')
else:
self.write('Not valid')
AdminHandler 列出了这些管理页面应该做什么的基本逻辑。 如果有人试图访问管理页面,处理程序应检查用户是否已登录,如果是,则允许访问该页面。如果没有,它会呈现登录页面。
重新排序、删除和添加都是我希望管理员能够执行的操作,但将来可能会有更多操作。我可以将 AdminHandler 逻辑添加到那些其他处理程序的所有 GET 和 POST,但这是非常重复的,因此我确信这是错误的做法。
正在寻找有关如何将 AdminHandler 的逻辑纳入涵盖 "administrative" 任务的所有其他处理程序的一些指导。
更新: Brent Washburne 为我指明了正确的方向,足以使它正常工作,尽管我仍然觉得我不了解装饰器函数的实际作用。无论如何,代码似乎可以正常工作,现在看起来像这样:
def require_user(old_func):
def new_function(self):
if not self.session.get('username'):
self.redirect('/signin')
old_func(self)
return new_function
class AdminHandler(BaseHandler):
@require_user
def get(self):
self.render('admin.html')
class AddHandler(BaseHandler):
@require_user
def get(self):
self.render('add.html')
@require_user
def post(self):
name = self.request.get('name')
qry = Animal.query(Animal.name == name).get()
if not qry:
new_animal = Animal(name=name)
new_animal.put()
self.write('OK')
所有其他 "admin" 处理程序依此类推。
这是一种确保用户在每个页面(登录页面除外)都登录的蛮力方法,或者将用户重定向到登录页面:
def dispatch(self):
# Get a session store for this request.
self.session_store = sessions.get_store(request=self.request)
if not self.session['username'] and self.request.get('path') != '/login':
return redirect('/login')
更好的方法是将此代码添加到每个 get() 和 put() 例程的顶部:
def get(self):
if not self.session['username']:
return redirect('/login')
更好的方法是将该代码变成装饰器,这样您只需添加一行:
@require_login
def get(self):
....