Password-Free login-python

Source: Internet
Author: User
Tags md5 encryption

To complete the background Management system login function, by looking at the login page, we can learn that we need to write a CAPTCHA image acquisition interface and login processing interface, and then write Ajax on the login page HTML.

Before the development of the interface, there is an important thing to deal with, that is to initialize the site, if not initialized, then the independent file writing interface will not be found, to write the exception error to the log file will not find the path, the following code first.

Open the main.py file and change to the following code (you can compare it with the previous code)

  1 #!/usr/bin/evn Python 2 # coding=utf-8 3 4 Import bottle 5 import sys 6 import OS 7 import logging 8 import ur Llib.parse 9 from bottle import Default_app, get, run, request, hooks from beaker.middleware import Sessionmiddleware 1 1 12 # import Tool function package from common import Web_helper, log_helper 14 # Import API code module (initialize the various access routes in the API folder, this sentence cannot be deleted, will not be able to access the API folder of the various interfaces ) Import API 16 17 ############################################# 18 # Initialize bottle Framework related parameters 19 ############################# ################ 20 # Gets the absolute path of the server where the current main.py file resides Program_path = Os.path.split (Os.path.realpath (__file__)) [0] 22 # Add a path to the Python environment variable sys.path.append (Program_path) 24 # To change the commit data to 2M max (if you want to upload more files, you can modify it here), bottle. Baserequest.memfile_max = 1024 * 1024 * 2 26 27 ############################################# 28 # Initialize log related parameters 29 ######### #################################### 30 # If the Log Directory Logs folder does not exist, create a log directory of If not os.path.exists (' log '): Os.mkdir (' log ') 33 # Initialize Log directory path Log_path = Os.path.join (program_path, ' log ') 35 # define log output format with path Logging.basicconfig (level=logging.info, PNs format= '% (asctime) s% (filename                     ) s[line:% (Lineno) d]% (levelname) s% (message) s ', filename= "%s/info.log"% Log_path, 39 Filemode= ' a ') 40 41 # Set Session parameter session_opts = {session.type ': ' File ', ' Session.cookie_expire S ': 3600, ' session.data_dir ': '/tmp/sessions/simple ', ' Session.auto ': True ~ @hook (' Before_req Uest ') def validate (): 52 "" "Use hook to handle interface access event" "" 53 54 # Gets the URL path of the current access Path_info = Request.environ.get ("Path         _info ") 56 # Filter The route without doing any action (i.e. filtering without having to judge whether to log in and log the URL) of the path_info in ['/favicon.ico ', '/', '/api/verify/']: 58 Return 59 # # # Record Client-submitted parameters # # 60 # Get the current access URL path with IP request_log = ' url: ' + path_info + ' IP: ' + web_helpe  R.get_ip () try:63 # Add JSON to submit parameters if request.json:65 Request_log = Request_log + ' params (JSON): ' + urllib. Parse.unquote (str (request.json)) except:67 pass try:69 # Add parameter for Get method submit if Reque st.query_string:71 Request_log = Request_log + ' params (get): ' + urllib.parse.unquote (str (request.query_strin g)) 72 # Add POST method to submit the parameters of the If Request.method = = ' Post ': Request_log = request_log + ' params (POST): ' + urllib.parse.unquote (str (request.params.__dict__)) 75 # stored in log file Log_helper.info (request_log  ) except:78 Pass 79 80 # handles AJAX-submitted requests such as put, delete, and so on to the corresponding request route (because Ajax does not support restful style submissions, so you need to handle this here and convert the Commit method) Bayi if Request.method = = ' POST ' and request. Post.get (' _method '): request.environ[' request_method '] = Request. Post.get (' _method ', ') 83 84 # Filter the route without login permission (log in and log out without checking whether you are logged in) Url_list = ["/api/login/", "/api/logout/"] If path_info in url_list:87 pass else:89 # Login Successful user session must have a value, no value is not logged in the Sessi On = Web_helper.get_seSsion () 91 # get User id manager_id = session.get (' id ', 0) login_name = session.get (' login_name ', 0) 94 # Determine if the user is logged in if not manager_id or not login_name:96 web_helper.return_raise (web_helpe R.return_msg (-404, "Your login has expired, please login Again")) 97 98 99 100 # Function Main Entry 101 if __name__ = = ' __main__ ': 102 APP_ARGV = Sessionmiddlew Is (Default_app (), session_opts) 103 run (APP=APP_ARGV, host= ' 0.0.0.0 ', port=9090, Debug=true, Reloader=true) 104 else:1 05 # When using UWSGI to process Python access, you must add this code, otherwise you will not be able to access 106 application = Sessionmiddleware (Default_app (), session_opts)

The main.py file has detailed explanatory notes, so do not elaborate, here is the general idea of the document.

Because the interface files that we write are placed in the API folder, when the Web service starts, we need to automatically load the interface files in the API, so that we can access the interface inside the URL, So need in main.py this entry function, the API folder in the interface file import, the previous explanation to our API folder has a __init__.py file, it will automatically help us to import all the files in the current folder, So we just need to add the import API to the main.py in this line of code.

In addition, we need to tell the Python service where the current program is located, so we need to add the absolute path where the current file resides to the Python environment variable (line 21st to 23rd)

We want to record the exception information to the log, to record the URL of the client access and the request parameters submitted, convenient error when help us to troubleshoot the error, so to initialize the log file format and storage path (line 30th to 39th)

The bottle framework has two easy-to-use hook handlers (such as a process), and when the client accesses the interface, it first enters from the bottle Web service bound entry, and then calls the Before_request hook function (line 50th to 97th). After executing the code inside and then entering the corresponding interface function, when the interface function is finished, it will call After_request this hook function (we used the nginx processing front-end access service does not exist cross-domain problems, So main.py did not add this hook function), run out of the code to return the final result to the client. So there are a lot of things we can do with these two hook functions. In Before_request we can run the initialization operation, log the URL of client access and request parameter operation, determine whether the user is logged in or not (if there is no such hook function, we have to determine whether the user is logged in, it must be processed in each interface file, On the one hand, the code is very redundant, there is a lot of duplication of unnecessary code, on the other hand is also prone to error or omission, resulting in back-end access to access vulnerabilities. and after_request This function through is used to handle the output HTTP header information and so on, such as cross-domain processing.

  

On line 55th to 78th, the URL of the client access is logged to the log with request parameters submitted in various ways. For some access that you do not want to log, you can add it to line 57th. such as

  

Line 90th to 96th, the login user access processing, if not logged in, it will return 404 status, the client's Ajax received this status, self-processing to jump to the login page.

  Authentication Code Interface

We create the verify.py file in the API folder

#!/usr/bin/python#coding:utf-8from IO import bytesiofrom bottle import get, Responsefrom Common import verify_helper, log _helper, Web_helper@get ('/api/verify/') def get_verify (): "" "    Generate Captcha Picture" "    try:        # get generate captcha picture with Captcha        Code_ IMG, Verify_code = Verify_helper.create_verify_code ()        # Converts a string into uppercase save to session        S = web_helper.get_session ()        s[' verify_code ' = Verify_code.upper ()        s.save ()        # output Picture stream        buffer = Bytesio ()        Code_img.save ( Buffer, "JPEG")        code_img.close ()        response.set_header (' Content-type ', ' image/jpg ')        return Buffer.getvalue ()    except Exception as E:        log_helper.error (str (E.ARGS))

code_img, Verify_code = Verify_helper.create_verify_code (): Runs Verify_helper.create_verify_code (), returns the picture stream and verification code, After the Python language executes functions, you can directly return values of various types, such as strings, numbers, tuples, dictionaries, lists, and so on, when you return a tuple type value, you can receive it in such a way.

Log_helper.error (str (E.ARGS)) This is the error logging function we talked about in front of the tool function pack, which logs exception information to the log file and sends an exception to the mailbox that we specify when generating an exception for the verification code.

After adding this file, we can run the main.py and enter http://127.0.0.1:9090/api/verify/or http://127.0.0.1:81/api/verify/in the browser. You can see the generated verification code (if you can't access it using port 81)

  

  Login interface

We create the login.py file in the API folder

 1 #!/usr/bin/evn Python 2 # coding=utf-8 3 4 from bottle Import put 5 from common import Web_helper, Encrypt_helper, db_ Helper 6 7 8 @put ('/api/login/') 9 def post_login (): 10 "" User Login Verification "" "11 ########################################## ################### #12 # Get and verify client-submitted parameters ############################################################# #14 user Name = Web_helper.get_form (' username ', ' account number ') Password = web_helper.get_form (' password ', ' password ') verify = Web_hel Per.get_form (' Verify ', ' Verification Code ')-IP = web_helper.get_ip () 18 19 #################################################### ######### #20 # Read the CAPTCHA information from the session ############################################################# #22 s = Web_hel Per.get_session () Verify_code = S.get (' Verify_code ') 24 # Delete the verification code in session (the verification code expires every time it is submitted) if ' Verify_code ' in S : $ del s[' Verify_code ']27 s.save () 28 # Determine if the verification code submitted by the user is the same as the verification code stored in session if Verify.upper ()! = Veri fy_code:30 returN Web_helper.return_msg (-1, ' captcha error ') ~ ############################################################# #33 # # # Get Login Employment record and login Verification # # #34 ############################################################# #35 sql = "" "SELECT * from Manage R where login_name= '%s ' "" "% (username,) 36 # Read user information from database PNs Manager_result = db_helper.read (SQL) 38 # Determine if the user record exists If not manager_result:40 return web_helper.return_msg (-1, ' account not present ') 41 42 ############################### ############################## #43 # # # Verify user login password and status # # #44 ########################################################## # # # # # # # # # # # # # # # # # # # # # # # # # MD5 encryption will be capitalized (for password confidentiality, double MD5 encryption, extract a string from the first encrypted string to encrypt again, extract the string you can freely set) # # PWD = Encryp T_HELPER.MD5 (ENCRYPT_HELPER.MD5 (password)). Upper () 47 # MD5 encryption will be capitalized (once encrypted only once) for authentication submitted by the client. PWD = Encrypt_helper . MD5 (password). Upper () 49 # Check that the login password is entered correctly if pwd! = Manager_result[0].get (' Login_password ', '): return Web_helper.return_msg (-1, ' password error ') 52 # Check that the account is not disabled if manager_result[0].get (' is_enable ', 0) = = 0:54 return web_helper.return_msg (-     1, ' account has been disabled ') ############################################################# #57 # # # to save user information to session # # #58 ############################################################# #59 manager_id = manager_result[0].get (' id ', 0) s[' Id '] = manager_id61 s[' login_name '] = username62 s.save () 63 64 ############################################### ############## #65 # # # Update user information to database # # #66 ############################################################# #67 # Update current Administrator last logon time, IP and login number (field description, see Data dictionary). last_login_time=%s sql = "" Update Manager set, last_login_ip=%s, Login_count=login_c ount+1 where id=%s "" "69 # Combination Update value of VARs = (' Now () ', IP, manager_id,) 71 # Write to Database (SQL, db_helper.write) Web_helper.return_msg return (0, ' login successful ')

Before writing the login interface, let's first understand what the process of login interface processing is.

  

login.py background Login Processing interface code can see that the route we use is @put ('/api/login/'), in restful style, post is used for new records, put is used to modify or change server data, login I understand it certainly is not new, It's changing the state of the user's login, so here's a put method to receive

Login interface Code has detailed comments, as well as the above flowchart, so no more in-depth commentary, we look at the code, if you do not understand, the article behind the message.

Front-End Login HTML page (login.html)

  1 <! DOCTYPE html> 2 

The previously downloaded login.html page was fine-tuned to add the requested AJAX code.

Since Firefox and Google run Ajax does not support the put, delete and other submissions, so Ajax commit type or post mode, in the commit parameter item, you need to add _method this parameter, the value is put. (Because this series uses a restful style, it's a bit of a hassle, but it doesn't affect our use)

HTML and JS I do not elaborate, we look at the code, if we all ask for JS to write comments, I will add comments into the.

The relevant page functions are complete, and the next step is to run the debugging

Enter in the browser: http://127.0.0.1:81/login.html then enter the account: admin, Password: 123456, and Verification code

  

Click Login, can normally jump to the http://127.0.0.1:81/main.html page, it means that the login interface can be used normally.

  

You want to be familiar with the operation of the login interface code, it is best to use the debug run tracking, see how each line of code is running, it is clear. Of course, if you want to deepen your understanding, the best way to do this is to follow the code, run it on a few lines, and see how it works.

Password-Free login-python

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.