Solve user verification problems in the Bottle framework by using the Python decorator
This article mainly introduces how to solve the user verification problem in the Python Bottle framework. The Code is based on Python2.x. For more information, see
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:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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:
?
1 2 3 4 5 6 7 8 9 10 11 |
Def p (): Print 'hello, world' Def funcfactor (func ): Print 'calling function named', func. _ name __ Return func Func = funcfactor (p) Func () # Output: # Calling function named p Hello, 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:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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 () # 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:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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 () # 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:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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 ") # 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:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Def blog_auth (func ): ''' Define a decorator for decorating the page to be verified The decorator must be placed under the route decorator. ''' # Define the packaging function Def wrapper (* args, ** kargs ): Try: # Reading cookies User = request. COOKIES ['user'] Shell = request. COOKIES ['shell'] Except t: # Redirect to the logon page if an exception occurs Redirect ('/login ') # Verifying user data If checkShell (user, shell ): # A function is returned if the verification is successful. 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:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@ Route ('/admin :#/? #') @ Blog_auth Def admin (): ''' Used to display the homepage of background management ''' 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 document list to the front-end Template TEMPLATE ['articles'] = articles Return template('admin.html ', TEMPLATE) |
Now the bottle verification problem has been solved elegantly with the decorator.