Solve the user verification problem in the Bottle framework by using the Python decorator, pythonbottle
First, analyze the requirements. The web application background requires authentication. The background page contains multiple pages. The most common method is to add authentication for each url, however, in this way, every backend function bound to a url needs to add similar or identical code, but the code is too redundant and not conducive to expansion.
Next, let's not talk about the decorator. We all know that Python is a very powerful language. She can pass functions as parameters to functions, which is the simplest:
Def p (): print 'hello, world' def funcfactor (func): print 'calling function named', func. _ name _ func () print 'end' funcfactor (p) # output: # calling function named p # Hello, world # end
A program that is clear at a glance defines a function p (), passes FUNCTION p as a parameter to shout out funcfactor, and adds some actions before and after executing the function p.
We can also do this:
Def p (): print 'hello, world' def funcfactor (func): print 'calling function named', func. _ name _ return funcfunc = funcfactor (p) func () # output: # calling function named pHello, world
As you can see, we can return the function and assign it to a variable for future calls. however, in this case, it is impossible to do something after the function is executed, but our Python is powerful. Python can nest a function in the function. We can do this as follows:
Def p (): print 'hello, world' def funcfactor (func): def wrapper (): print 'Do something at start' func () print 'Do something at end' return wrapperfunc = funcfactor (p) func () # output: # do something at start # Hello, world # do something at end
Next let's take a look at the decorator. Although the above Code implements a very difficult task, it is not elegant enough, and the Code does not conform to the Python philosophy, as a result, the decorator does not work in the same way as the above. It is also used for packaging functions, but the code implementation is more elegant and easy to read. the decorator starts with @ and follows the name of the decorator. The next line is the function body to be packaged. The above example can be implemented using the decorator as follows:
Def decorator (func): def wrapper (): print 'Do something at start' func () print 'Do something at end' return wrapper @ decoratordef p (): print 'hello, world 'P () # output: # do something at start # Hello, world # do something at end
In fact, the decorator does not improve the performance or other aspects. It is just a syntactic sugar, that is, the above example is rewritten, so it is more elegant and easy to read. if our p () function doesn't just want to lose Hello, world, we want to say Hello to someone we specified:
Def decorator (func): def wrapper (* args, ** kargs): print 'Do something at start' func (** kargs) print 'Do something at end' return wrapper @ decoratordef p (name): print 'hello', namep (name = "Jim") # output: # do something at start # Hello Jim # do something at end
It is not necessary for the decorator to nest a function without parameters for decoration. If the decorated function requires parameters, a function must be nested to process parameters. I am sure you know the usage and functions of the decorator. now back to the question, how can I elegantly Add the verification function to the background url? There is no doubt that we use the decorator to handle the problem:
Def blog_auth (func): ''' defines a decorator. The page decorator to be verified must be placed under the route decorator ''' # defines the packaging function def wrapper (* args, ** kargs): try: # Read cookie user = request. COOKIES ['user'] shell = request. COOKIES ['shell'] failed T: # redirect to redirect ('/login') on the logon page if an exception occurs # verify user data if checkShell (user, shell ): # If the verification succeeds, return the function return func (** kargs) else: # Otherwise, redirect to the logon page redirect ('/login') return wrapper
You can add the blog_auth decorator where the verification is required:
@ Route ('/admin :#/? # ') @ Blog_authdef admin (): ''' is used to display the Background Management Homepage ''' TEMPLATE ['title'] = 'dashboard | '+ TEMPLATE ['blog _ name'] TEMPLATE ['user'] = request. COOKIES ['user'] articles = [] for article in db. posts. find (). sort ("date", DESCENDING ). limit (10): articles. append (article) # submit the article list to the front-end TEMPLATE ['Article'] = articles return template('admin.html ', TEMPLATE)
Now the bottle verification problem has been solved elegantly with the decorator.