利用Python的装饰器解决Bottle框架中用户验证问题
来源: 阅读:886 次 日期:2015-04-28 14:17:19
温馨提示: 小编为您整理了“利用Python的装饰器解决Bottle框架中用户验证问题”,方便广大网友查阅!

这篇文章主要介绍了Python的Bottle框架中解决用户验证问题,代码基于Python2.x版本,需要的朋友可以参考下

首先来分析下需求,web程序后台需要认证,后台页面包含多个页面,最普通的方法就是为每个url添加认证,但是这样就需要每个每个绑定url的后台函数都需要添加类似或者相同的代码,但是这样做代码就过度冗余,而且不利于扩展.

接下来我们先不谈及装饰器,我们都知道Python是个很强大的语言,她可以将函数当做参数传递给函数,最简单的:

def p():

print 'Hello,world'

def funcfactor(func):

print 'calling function named', func.__name__

func()

print 'end'

funcfactor(p)

# 输出为:

# calling function named p

# Hello,world

# end

一目了然的程序,定义一个函数p(),将函数p当做参数传递给喊出funcfactor,在执行p函数前后加上一些动作.

我们还可以这么做:

def p():

print 'Hello,world'

def funcfactor(func):

print 'calling function named', func.__name__

return func

func = funcfactor(p)

func()

# 输出为:

# calling function named p

Hello,world

正如你看到的,我们可以将函数返回然后赋予一个变量,留待稍后调用.但是这种情况下我们要想在函数执行后做点什么就不可能,但是我们的Python是强大的,Python可以在函数中再嵌套一个函数,我们可以像下面这么做:

def p():

print 'Hello, world'

def funcfactor(func):

def wrapper():

print 'do something at start'

func()

print 'do something at end'

return wrapper

func = funcfactor(p)

func()

#输出为:

# do something at start

# Hello, world

# do something at end

下面我们来看看装饰器,上面的代码虽然实现的一个很困难的任务,但是还不够优雅,而且代码不符合Python的哲学思想,所以装饰器就应声而出,装饰器没有和上面的原理相同,同样用于包装函数,只是代码实现上更加优雅和便于阅读.装饰器以@开头后面跟上装饰器的名称,紧接着下一行就是要包装的函数体,上面的例子用装饰器可用如下方式实现:

def decorator(func):

def wrapper():

print 'do something at start'

func()

print 'do something at end'

return wrapper

@decorator

def p():

print 'Hello, world'

p()

#输出为:

# do something at start

# Hello, world

# do something at end

实际上装饰器并没有性能方面或其他方面的提升,仅仅是一种语法糖,就是上面一个例子的改写,这样更加优雅和便与阅读. 如果我们的p()函数不想仅仅只输Hello,world,我们想向某些我们指定的人打招呼:

def decorator(func):

def wrapper(*args, **kargs):

print 'do something at start'

func(**kargs)

print 'do something at end'

return wrapper

@decorator

def p(name):

print 'Hello', name

p(name="Jim")

#输出为:

# do something at start

# Hello Jim

# do something at end

装饰器在装饰不需要参数的装饰器嵌套函数不是必须得,如果被装饰的函数需要参数,必须嵌套一个函数来处理参数. 写到这里想必大家也知道装饰器的用法和作用.现在回到正题,如何优雅的给后台url加上验证功能?毫无疑问我们使用装饰器来处理:

def blog_auth(func):

'''

定义一个装饰器用于装饰需要验证的页面

装饰器必须放在route装饰器下面

'''

# 定义包装函数

def wrapper(*args, **kargs):

try:

# 读取cookie

user = request.COOKIES['user']

shell = request.COOKIES['shell']

except:

# 出现异常则重定向到登录页面

redirect('/login')

# 验证用户数据

if checkShell(user, shell):

# 校验成功则返回函数

return func(**kargs)

else:

# 否则则重定向到登录页面

redirect('/login')

return wrapper

可以再需要验证的地方添加blog_auth装饰器:

@route('/admin:#/?#')

@blog_auth

def admin():

'''

用于显示后台管理首页

'''

TEMPLATE['title'] = '仪表盘 | ' + TEMPLATE['BLOG_NAME']

TEMPLATE['user'] = request.COOKIES['user']

articles = []

for article in db.posts.find().sort("date",DESCENDING).limit(10):

articles.append(article)

# 将文章列表交给前台模版

TEMPLATE['articles'] = articles

return template('admin.html',TEMPLATE)

至此bottle验证的问题就很优雅的用装饰器解决了.

更多信息请查看IT技术专栏

更多信息请查看网络编程
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!

2025国考·省考课程试听报名

  • 报班类型
  • 姓名
  • 手机号
  • 验证码
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map