Foreword
In the app open interface api design, can not avoid is the security issue, because most interfaces related to the user's personal information and sensitive data, so these interfaces need to authenticate identity,
This then requires the user to provide some information, such as user name and password, etc., but for safety reasons so that the number of users exposed plaintext password as possible, we are generally in a web project, in most cases, the saved session,
And then to keep a cookie, to maintain the validity of the user's answer. But in the open interface provided by the app, the back-end server How to verify and maintain the effectiveness of landing the user after the user logs do?
design
Api interfaces for sensitive, use https protocol
https is added to the hypertext transfer protocol http SSL layer, between which a communication network is encrypted, an encryption certificate is required. https protocol requires ca certificate, generally require payment.
1, the principle
When users log in to the server after the user authentication information (such as account and password), the authentication server to the client to return after a PID token user access to information again,
Bring this token, if the token Zhengqu, the data is returned. For obtaining the Token information, access user interfaces, client request url you need to take the following parameters:
① timestamp: timestamp ② token PID: PID (in which we give is defined as PID)
Then all the parameters requested by the user (including the timestamp, pid), then more MD5 encrypted (some salt may be added), generation of dynamic url.
Then the user login information each call, bring timestamp, pid parameters.
? Plus URL after the time stamp and pid: http: //127.0.0.1: 8888 / index pid = d073dae99f70b0cda2fa1ef8d25c527f | 1475117419.5424652 | 0
It becomes a relatively dynamic and has a high safety, to ensure the security of data access.
2, the specific implementation
1. api client wishes to request a server transmitting user authentication information (username and password), the server requests the change request, the user authentication information is correct.
If it is correct: a unique non-repeating string is returned, then maintain the user information in relation Redis (any cache server), so that other api check for the pid.
If the error: error code is returned.
2. The server design a url request blocking rules
① comprises determining whether the timestamp, pid parameters, return error code if not contained. ② The url parameters of the user request, the server generates a dynamic under the same rules of the URL, the dynamic contrast with the server url requests generated are equal, it is equal released to allow access. ③ determination server receives the request and time stamp parameters differ by a long period of time (such as custom time 10 seconds), it indicates that the url exceeds expired. ④ the dynamic URL recording each request, a predetermined dynamic URL accessed only once, each time detecting whether a request through the request url, Been presence returns an error code (url intercepted and processing requests within ten seconds of access ). ⑤ this url to intercept only to obtain authentication url release (such as landing url), all the rest are subject to the url interception.
3. Regular dynamic process preserved the request URL
Code
Rules of the server
! # / usr / bin / env Python # - * - Coding: UTF-8 - * - Import tornado.ioloop Import tornado.web Import hashlib Import Time access_record = [] # Create the first time you log in through the URL list PID_LIST = [# pid list 'QWE', 'ioui', '234S', ] class MainHandler (tornado.web.RequestHandler): DEF GET (Self): # in all data acquired url pid = self.get_argument ( 'pid', None) # acquisition variable m5, client_time, i = pid.split ( '|') # obtain data to with "|" open print (m5, client_time, i) the current time server_time = time.time () # service side # longer than 10s ban if server_time> float (client_time) + 10:# The current time is greater than the client services side of the current time plus 10 seconds, indicating that expired does not allow access self.write ( 'Gun') return # 10s deal with duplicate content request if pid in access_record: # if the client requests a dynamic URL in the first log off the list the URL self.write ( 'Gun') return access_record. append (pid) # allowed url by adding to the list pid = pID_LIST [int (i) ] # carried back pid obtain client to digital ramdom_str = "% s |% s "% (pid, client_time) # and the customer's current timestamp splicing pid h = hashlib.md5 () # MD5 encrypted value h .update (bytes (ramdom_str, encoding = 'utf-8')) # customer's current timestamp with the pid and then stitching a dedicated md5 encrypted string server_m5 = h.hexdigest () # server dynamically generates the URL # Print ( m5, server_m5) if m5 == server_m5: # client and server generated the generated comparison self.write ( "the Hello, World") the else: self.write ( 'Gun') file application tornado.web.Application = ([ (R & lt "/ index ", MainHandler), ]) IF __name__ ==" __main__ ": application.listen (8888) tornado.ioloop.IOLoop.instance () Start ().
The client generated by the rules in line with the
! # / usr / bin / env Python # - * - Coding: UTF-8 - * - Import Time Import Requests Import hashlib PID = 'QWE' # clients PID CURRENT_TIME = time.time () # current timestamp ramdom_str = " % s |% s "% ( pID, current_time) # pid the current timestamp and assembled into a string h = hashlib.md5 () # md5 encryption h.update (bytes (ramdom_str, encoding = 'utf-8') ) # pid and the current timestamp then assembled into a string md5 encrypted UID = string () # h.hexdigest after encryption q = "% s |% s | 0"% (UID, current_time) # in the the string following the splicing a value 0 URL = 'http://127.0.0.1:8888/index?pid=%s' Q #% last generated dynamically generated URL Print (URL) RET = requests.get (URL) Print (ret.text)
Test results Code
#!/usr/bin/env python # -*- coding:utf-8 -*- import requests ret = requests.get('http://127.0.0.1:8888/index?pid=c2539948caa7b7fe0d00fcd9d75b7574|1474341577.4938722|0') print(ret.text)
This is a fairly thick ultra-API authentication mechanism, it can be a preliminary understanding.
zhuan: https: //www.cnblogs.com/kongqi816-boke/p/5919385.html