利用Python的装饰器解决Bottle框架中用户验证问题

首先来分析下需求,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验证的问题就很优雅的用装饰器解决了.

(0)

相关推荐

  • Python的Bottle框架中获取制定cookie的教程

    这两天为用bottle+mongodb写的一个项目加上登录功能,无奈怎么都获取不到保存的cookie,文档给出让我们这样操作cookie的代码片段: @route('/login') def login (): username = request .forms .get('username ') password = request .forms .get('password ') if check_user_credentials(username, password): response

  • 简单的连接MySQL与Python的Bottle框架的方法

    Python关于mySQL的连接插件众多,Bottle下也有人专门开发的插件:bottle-mysql具体使用方法见官方,总共感觉其用法限制太多,其使用起来不方便,最适合的当然是,mySQL官网给Python提供的通用官方驱动,用起来很顺手:mysql-connector  具体操作如下: # -*- coding: utf-8 -*- #!/usr/bin/python # filename: login_admin.py # codedtime: 2014-9-7 11:26:11 impo

  • Python的Bottle框架中实现最基本的get和post的方法的教程

    1.GET方式: # -*- coding: utf-8 -*- #!/usr/bin/python # filename: GETPOST_test.py # codedtime: 2014-9-20 19:07:04 import bottle def check_login(username, password): if username == '123' and password == '234': return True else: return False @bottle.route

  • Python的Bottle框架的一些使用技巧介绍

    之前对bottle做过不少的介绍,也写过一些文章来说明bottle的缺点,最近发现其实之前有些地方说的不太公平,所以趁此机会也来更正一下. bottle是支持类似flask url_for的语法的,具体使用方法在下文介绍     bottle的request.query之类的参数默认是str类型,也是有原因的,比如我在给google做代理的时候,编码就不一定是utf8的,如果强制转化utf8就会报错     之前的bug也得到了修正,比如mount('/x',app)之后,/x/和/x都可以访问

  • 在Python的Bottle框架中使用微信API的示例

    微信这个东西估计宅男没几个不熟悉的吧,微信经过这么两年多的发展终于向开放平台跨出了友好的一步.蛋疼的以为微信会出一个详细的api等接口,兴奋不已的去申请了微信公共平台,然后开始找各种api的位置-- 花费了近一个小时,依然没找到-- 最后动用Google大杀器,终于找到了这么个链接.我了个去的,没比这还简单的api文档了吧. 最让人无法理解的是:居然没有本地开发环境支持,每次都要放在生产环境去调试. 最让人欣慰的是:就那么俩方法,生产环境调试几次也就完事了. Python(bottle)版代码如

  • Bottle框架中的装饰器类和描述符应用详解

    最近在阅读Python微型Web框架Bottle的源码,发现了Bottle中有一个既是装饰器类又是描述符的有趣实现.刚好这两个点是Python比较的难理解,又混合在一起,让代码有些晦涩难懂.但理解代码之后不由得为Python语言的简洁优美赞叹.所以把相关知识和想法稍微整理,以供分享. 正文 Bottle是Python的一个微型Web框架,所有代码都在一个bottle.py文件中,只依赖标准库实现,兼容Python 2和Python 3,而且最新的稳定版0.12代码也只有3700行左右.虽然小,但

  • Python的Bottle框架中返回静态文件和JSON对象的方法

    代码如下: # -*- coding: utf-8 -*- #!/usr/bin/python # filename: todo.py # codedtime: 2014-8-28 20:50:44 import sqlite3 import bottle @bottle.route('/help3') def help(): return bottle.static_file('help.html', root='.') #静态文件 @bottle.route('/json:json#[0-9

  • 利用Python的装饰器解决Bottle框架中用户验证问题

    首先来分析下需求,web程序后台需要认证,后台页面包含多个页面,最普通的方法就是为每个url添加认证,但是这样就需要每个每个绑定url的后台函数都需要添加类似或者相同的代码,但是这样做代码就过度冗余,而且不利于扩展. 接下来我们先不谈及装饰器,我们都知道Python是个很强大的语言,她可以将函数当做参数传递给函数,最简单的: def p(): print 'Hello,world' def funcfactor(func): print 'calling function named', fun

  • python @property 装饰器使用方法

    目录 一.property的装饰器用法 二.举例说明 1.不用setter和getter方法的实现 2.使用setter和getter的实现,增加温度值输入的限制 3.利用property装饰器实现的版本 一.property的装饰器用法 先简单上个小栗子说明: class property(fget=None,fset=None,fdel=None,doc=None) fget是用于获取属性值的函数 fset是用于设置属性值的函数 fdel是用于删除属性值的函数 doc为属性对象创建文档字符串

  • python知识:装饰器@property到底有啥用途

    目录 一.提要 二.关于属性的约定 2.1 类绑定属性 2.2 对象绑定属性 2.3 私有属性 三.应用@property装饰器 3.1 将一个属性转成方法 3.2 私有化某些属性 3.3 关联性修改 3.4 删除属性的deleter方法 四.property()函数原理 总结 一.提要 python的@property是python的一种装饰器,是用来修饰方法的. python @property 装饰器使一个方法可以像属性一样被使用. 除此之外,还有几个使用场景,本文将叙述这些使用技巧. 二

  • python函数装饰器用法实例详解

    本文实例讲述了python函数装饰器用法.分享给大家供大家参考.具体如下: 装饰器经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计, 有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能. #! coding=utf-8 import time def timeit(func): def wrapper(a): start = time.clock() func

  • Python使用装饰器进行django开发实例代码

    本文研究的主要是Python使用装饰器进行django开发的相关内容,具体如下. 装饰器可以给一个函数,方法或类进行加工,添加额外的功能. 在这篇中使用装饰器给页面添加session而不让直接访问index,和show.在views.py中 def index(request): return HttpResponse('index') def show(request): return HttpResponse('show') 这样可以直接访问index和show,如果只允许登陆过的用户访问i

  • Python函数装饰器常见使用方法实例详解

    本文实例讲述了Python函数装饰器常见使用方法.分享给大家供大家参考,具体如下: 一.装饰器 首先,我们要了解到什么是开放封闭式原则? 软件一旦上线后,对修改源代码是封闭的,对功能的扩张是开放的,所以我们应该遵循开放封闭的原则. 也就是说:我们必须找到一种解决方案,能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能. 总结:原则如下: 1.不修改源代码 2.不修改调用方式 目的:在遵循1和2原则的基础上扩展新功能. 二.什么是装饰器? 器:指的是工具, 装饰:指的是为被装饰对象添加

  • Python函数装饰器原理与用法详解

    本文实例讲述了Python函数装饰器原理与用法.分享给大家供大家参考,具体如下: 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓存.权限校验等应用场景.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能. 严格来说,装饰器只是语法糖,

  • python重试装饰器的简单实现方法

    简单实现了一个在函数执行出现异常时自动重试的装饰器,支持控制最多重试次数,每次重试间隔,每次重试间隔时间递增. 最新的代码可以访问从github上获取 https://github.com/blackmatrix7/matrix-toolkit/blob/master/toolkit/retry.py #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2017/8/18 上午9:50 # @Author : Matrix # @Git

  • python @propert装饰器使用方法原理解析

    这篇文章主要介绍了python @propert装饰器使用方法原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 首先,@propert的作用是把类中的方法『变成』了属性,方便通过实例访问.propert可以有两种用法:可以把一个方法变成只读属性:可以对一些属性进行过滤. 想象这样一个场景,在实例化一个类之后,需要对类的一个属性进行赋值,这时候是没有对属性属性被赋予的值进行判断的,如果属性被赋予了一个不合适的值,那么代码在后面执行的时候就会

随机推荐