(不是web背景)
最近突然想到有些app會打開預設瀏覽器讓user做登入或是授權之類的動作,
但卻可以在user操作完之後收到callback?
但app和瀏覽器之間應該沒有IPC啊?這是怎麼做到的?
經過一陣子的研究發現是透過local建立一個http server監聽callback url,在叫起browser的時候把callback url夾帶在url parameter內,讓server端在做完之後把user redirect到callback url來達成的。
微軟寫在身份驗證服務的說明文件: Redirect URI (reply URL) outline and restrictions
知道這個特性之後就決定用python寫個POC來練手一下,之後如果有需要用到就可以直接拿來用。
Server:
from http.server import BaseHTTPRequestHandler, HTTPServer
import urllib.parse
class SimplePageHandler(BaseHTTPRequestHandler):
def do_GET(self):
= urllib.parse.urlparse(self.path)
parsed = urllib.parse.parse_qs(parsed.query)
params = params.get('callback', [''])[0]
callback_url
= f"""
html <html>
<body>
<h1>Click to trigger callback to: {callback_url}</h1>
<form action="{callback_url}">
<button type="submit">Go to Callback URL</button>
</form>
</body>
</html>
"""
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(html.encode('utf-8'))
if __name__ == '__main__':
print("====== SERVER ======")
= ('0.0.0.0', 8000)
server_address print(f"Starting server at port {server_address[1]}")
print(f"Visit in browser:")
print(f"http://<domain>:{server_address[1]}/?callback=<your_callback_url>")
= HTTPServer(server_address, SimplePageHandler)
httpd httpd.serve_forever()
Client:
from http.server import BaseHTTPRequestHandler, HTTPServer
class CallbackHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path.startswith("/callback"):
print(f"Received callback at {self.path}")
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(b'===== CLIENT =====\n')
self.wfile.write(b'Callback received!')
else:
self.send_response(404)
self.end_headers()
if __name__ == '__main__':
print("===== CLIENT =====")
= ('localhost', 9000)
server_address print(f"Starting client callback server at http://{server_address[0]}:{server_address[1]}/callback")
= HTTPServer(server_address, CallbackHandler)
httpd httpd.serve_forever()
嘗試把server.py丟到區網上的raspberry pi 3裡面執行,從PC打開client.py跟網頁,並把callback URL帶過去,確實可以這樣用。
![]() |
留言
張貼留言
因為廣告太多了,留言會經過審核才顯示。通常我會每天看。