What can You Learn in this Course?
Master the key points of API development
Understand JSONPath
Understand intranet penetration
Course Content
Key Points of API Development
Preview of push format
Go to Extension > Webhook > Field Comparison Table and JSON Example.
1. Determine the push type*
op: Push events include data_create(data creating), data_update(data updating), data_remove(data deleting), and data_recover(data recovering).
Use op to distinguish specific push events
from flask import Flask, request import jsonapp = Flask(__name__) @app.route('/test/', methods=['POST']) #Only POST requests are received in Jodoo def hello_world(): print("params: ",request.args) print("headers: ",request.headers) print("Encoded data: ",request.data) print("Unencoded data: ",json.loads(request.data)) return 'success',200if __name__ == '__main__': app.run(host='0.0.0.0',port=10000)
url: http://101.132.103.228:10000/test/?nonce=5932d0×tamp=1585724440params: ImmutableMultiDict([('nonce', '5932d0'), ('timestamp', '1585724440')])headers: Content-Type: application/json X-Jdy-Deliverid: 2b85594d-454a-4063-ac1d-91a2b3318b63 Host: 101.132.103.228:10000 Content-Length: 765 Connection: closeRaw data: b'{"data":{"_id":"5dd6740646357c0006e6eb6e","_widget_1574134687834":"\xe6\xb6\xa1\xe8\xbd\xae\xe5\x87\x8f\xe9\x80\x9f\xe6\x9c\xba1","_widget_1574134687849":"DJSM9K2000","_widget_1574134687894":"2019-11-21T11:24:54.000Z","_widget_1574134688078":345999,"_widget_1574134688093":101,"_widget_1574134688108":3459990,"_widget_1574134688185":"\xe5\x8d\x97\xe4\xba\xac\xe6\x82\x9f\xe5\xb8\x86\xe7\xa7\x91\xe6\x8a\x80\xe8\x82\xa1\xe4\xbb\xbd\xe6\x9c\x89\xe9\x99\x90\xe5\x85\xac\xe5\x8f\xb8","_widget_1574142293244":"TSCJ001574335494","appId":"5dce13f43087860006c70e7a","createTime":"2019-11-21T11:24:54.213Z","creator":{"_id":"5cecd40dd23e194ab0867aab","name":"\xe6\x9f\xa5\xe7\x90\x86","username":"cxt7777"},"deleteTime":null,"deleter":null,"entryId":"5dce145c26aecf00062e7db0","formName":"\xe8\xae\xa2\xe5\x8d\x95\xe6\xb1\x87\xe6\x80\xbb","updateTime":"2020-04-01T07:00:40.876Z","updater":{"_id":"5cecd40dd23e194ab0867aab","name":"\xe6\x9f\xa5\xe7\x90\x86","username":"cxt7777"}},"op":"data_update"}'The data that are converted into a dictionary in Python: {'data': {'_id': '5dd6740646357c0006e6eb6e', '_widget_1574134687834': 'machine 1', '_widget_1574134687849': 'DJSM9K2000', '_widget_1574134687894': '2019-11-21T11:24:54.000Z', '_widget_1574134688078': 345999, '_widget_1574134688093': 101, '_widget_1574134688108': 3459990, '_widget_1574134688185': 'Jodoo Technology Co., Ltd.', '_widget_1574142293244': 'TSCJ001574335494', 'appId': '5dce13f43087860006c70e7a', 'createTime': '2019-11-21T11:24:54.213Z', 'creator': {'_id': '5cecd40dd23e194ab0867aab', 'name': 'Martin', 'username': 'cxt7777'}, 'deleteTime': None, 'deleter': None, 'entryId': '5dce145c26aecf00062e7db0', 'formName': 'Order Summary', 'updateTime': '2020-04-01T07:00:40.876Z', 'updater': {'_id': '5cecd40dd23e194ab0867aab', 'name': 'Martin', 'username': 'cxt7777'}}, 'op': 'data_update'}
2. Multi-threading processing
Threading: In Python, you need to use the threading module to implement multi-threading programming. Multi-threading is often used to prevent response timeout caused by long processing time.
Multi-threading is a programming technique that allows multiple threads to run concurrently within a single process.
It can be used to execute tasks in the background that take a long time to complete, freeing up resources for other tasks.
Multi-threading can also be used to enhance user interfaces by displaying progress bars or other indicators of task completion when an event is triggered by the user.
In addition, multi-threading can accelerate program execution by running multiple threads simultaneously. This is particularly useful for tasks that involve waiting for user input, file reading and writing, or network data transmission. In these cases, threads can be used to free up resources such as memory usage.
threading.Thread(target=<Function name>).start() # Multi-threading assignment threading.Thread(target=<Function name>, args=(<Variable>,).start()
import threading import timedef handle_a(): for i in range(5): print("a",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) ) time.sleep(1) def handle_b(): for i in range(5): print("b",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) ) time.sleep(1) #Use multi-threading threading.Thread(target=handle_a).start() time.sleep(0.1) handle_b()#Execute functions in a normal sequential order. handle_a() handle_b()#Import parameters def printtime(a): print(a, time.time()) x = 123threading.Thread(target=print,args=(x,)).start()
3. API encryption
Encryption: To prevent the API from being attacked.
import hashlibdef get_signature(nonce, payload, secret, timestamp): content = ':'.join([nonce, payload, secret, timestamp]).encode('utf-8') m = hashlib.sha1() m.update(content) return m.hexdigest()@app.route('/callback', methods=['POST']) def callback(): payload = request.data.decode('utf-8') nonce = request.args['nonce'] timestamp = request.args['timestamp'] if request.headers['x-jdy-signature'] != get_signature(nonce, payload, 'test-secret', timestamp): return 'fail', 401 threading.Thread(target=handle, args=(json.loads(payload), )).start() return 'success'
JSONPath
Click to test.
{ "data": [ { "creator": { "_id": "5cecd40dd23e194ab0867aab", "name": "Martin", "username": "cxt7777" }, "updater": { "_id": "5cecd40dd23e194ab0867aab", "name": "Martin", "username": "cxt7777" }, "deleter": null, "createTime": "2020-03-26T02:41:06.491Z", "updateTime": "2020-03-26T02:46:27.825Z", "deleteTime": null, "_widget_1557886562320": "iPhone 11", "_widget_1557886562335": "5998", "_widget_1557886562350": "17", "_id": "5e7c164229e01a00063be284", "appId": "5e798363b587cc0006b40445", "entryId": "5cdb765b5a6ae613aeed0f84" }, { "creator": { "_id": "5cecd40dd23e194ab0867aab", "name": "Martin", "username": "cxt7777" }, "updater": { "_id": "5cecd40dd23e194ab0867aab", "name": "Martin", "username": "cxt7777" }, "deleter": null, "createTime": "2020-03-26T02:47:02.037Z", "updateTime": "2020-03-26T02:47:02.037Z", "deleteTime": null, "_widget_1557886562320": "iPhone X", "_widget_1557886562335": "4998", "_widget_1557886562350": "5", "_id": "5e7c17a650bccb0006441778", "appId": "5e798363b587cc0006b40445", "entryId": "5cdb765b5a6ae613aeed0f84" }, { "creator": { "_id": "5cecd40dd23e194ab0867aab", "name": "Martin", "username": "cxt7777" }, "updater": { "_id": "5cecd40dd23e194ab0867aab", "name": "Martin", "username": "cxt7777" }, "deleter": null, "createTime": "2020-03-26T02:47:43.059Z", "updateTime": "2020-03-26T02:47:43.059Z", "deleteTime": null, "_widget_1557886562320": "iPhone 8", "_widget_1557886562335": "3998", "_widget_1557886562350": "32", "_id": "5e7c17cfcd87510006cf8189", "appId": "5e798363b587cc0006b40445", "entryId": "5cdb765b5a6ae613aeed0f84" } ] }
The extraction rules are similar to those in Python:
Extract the quantity of iPhone 11 products ("_widget_1557886562350")
$.data[0]._widget_1557886562350
$.data[0][‘_widget_1557886562350’]
Intranet Penetration (Demo)
Now, the APIs we have developed can only be accessed locally (your own host, localhost, or 127.0.0.1). We need to map the local port to the public network environment before it can be accessed by Jodoo or other people (you only need to know what is intranet penetration, instead of mastering it).
The APIs we have developed can currently only be accessed on the local machine, using the localhost or 127.0.0.1 address. To make these APIs accessible from outside the local machine, we need to map the local port to the public network environment. (You only need to understand the basic concepts and techniques involved, instead of being an expert in intranet penetration.)
Of course, you can also directly deploy the service on a cloud server (ECS) with a public network address. We will introduce it in the next course.
We have written an API, and both the request and response formats are JSON.
from flask import Flask, request import jsonapp = Flask(__name__) @app.route('/test/', methods=['POST']) #Only POST requests are received in Jodoo def hello_world(): print("params: ",request.args) print("headers: ",request.headers) print("Unencoded data: ",request.data) print("Encoded data: ",json.loads(request.data)) return 'success',200if __name__ == '__main__': app.run(host='0.0.0.0',port=3100)
I have finished reading. 🏆
👉I can't wait to USE THE API.
👉I need more HELP in Discord Forum.