tornado: web.py 之 Authenticated

小半个晚上只干了一件事,研究web.py里面的authenticated方法。 

 

先看这个函数的注释: 

 

"""Decorate methods with this to require that the user be logged in."""

 

 

所以基本这个很清楚了,假设你有一个handler,而这个handler中有一个方法调用需要用户已登录,例如:

 

class TrasactionManager:
    def getTransactionDetail(self, id):
        blahblahblah

 我们需要保证只有已经登录的用户才能调用到getTransactionDetail方法,那么,使用authenticated这个装饰器,来保证这个函数被调用前tornado会做相应的检查,修改后如下:

 

 

class TrasactionManager:

    @authenticated
    def getTransactionDetail(self, id):
        blahblahblah

 

 

当然了,这是其然,其所以然本菜鸟研究了半天。。。

首先就对python中的decorator不熟,谷歌了一下,找了一篇文章(http://blog.donews.com/limodou/archive/2004/12/19/207521.aspx),大致了解了怎么回事:

  1. 首先authenticated是不带参数的(method)这个参数除外
  2. 其次所有decorator修饰的方法会被python解释器“预处理”,例如:
    def simpleDecorator(method):
         print "This is a decorator"
         return method
    
    @simpleDecorator
    def simpleMethod():
         print "This is a method been decorated"
     这个例子里,simpleMethod会被预处理为simpleMethod = simpleDecorator(simpleMethod)

所以,前面前面的例子中,类TrasactionManager中的getTransactionDetail实际上会变成这样getTransactionDetail=authenticated(getTransactionDetail),嗯原理就是这样了,不过尼嘛authenticated里面又定义了一个用装饰器修饰的方法,这就绕了。。。。最后我整理了一下,整个decorating流程大致成了这样:

@authenticated
def getTransactionDetail(self, id):
    ‘’‘logic to get the transaction detail information
    which is bundle to specific user'''
    check_transaction_detail_of_current_user_by_id

getTransactionDetail = authenticated(getTransactionDetail)
	    = (functools.wraps(getTransactionDetail))(authenticated.wrapper) 
	    = (update_wrapper(wrapper #这个wrapper是update_wrapper方法的parameter place holder,
	           getTransactionDetail,
	           assigned = WRAPPER_ASSIGNMENTS,
	           updated = WRAPPER_UPDATES))(authenticated.wrapper)
	    = update_wrapper(authenticated.wrapper,
	           getTransactionDetail,
	           assigned = WRAPPER_ASSIGNMENTS,
	           updated = WRAPPER_UPDATES)
	    = Mixin-ed authenticated.wrapper

 

老实说,看了update_wrapper代码,我觉得除了默认定义的这些个属性外(

WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')

 ),没觉得__dict__里面有啥有用的东西,嗯,大概是我修为还不够

 

所以呢,经过上面一番折腾,参考authenticated的源代码,我们可以认为,这个getTransactionDetail已经面目全非,变成了另外一个样子。。

def getTransactionDetail(self, id):
        if not self.current_user:
            if self.request.method in ("GET", "HEAD"):
                url = self.get_login_url()
                if "?" not in url:
                    if urlparse.urlsplit(url).scheme:
                        # if login url is absolute, make next absolute too
                        next_url = self.request.full_url()
                    else:
                        next_url = self.request.uri
                    url += "?" + urllib.urlencode(dict(next=next_url))
                self.redirect(url)
                return
            raise HTTPError(403)
    ‘’‘logic to get the transaction detail information
    which is bundle to specific user'''
    check_transaction_detail_of_current_user_by_id

 

 注意最后三行高亮的部分,这正是原getTransactionDetail方法的方法体,但在之前,则加入了验证用户已经登录的逻辑。

 

所以,举一反三,我们也可以设计出其他更加复杂的验证机制,例如只有site admin才能执行的函数(例如偷摸从客户账面转走1W元这样的)

 

顺便记录三篇据说是大湿的系列文章,好长。。。。留着以后看

http://blog.csdn.net/beckel/article/details/3585352

http://blog.csdn.net/beckel/article/details/3945147

http://blog.csdn.net/beckel/article/details/4072886

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值