You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建接收单次请求即终止的Python简易HTTPS服务器?

最简Python SSL服务器问题解决(用于Slack OAuth重定向)

需求目标

  • 搭建仅接收一次请求后即终止的最简Python服务器,用于接收Slack OAuth链接的重定向响应

第一版代码及问题

代码实现

import http.server
from ssl import SSLContext


class MyHandler(http.server.SimpleHTTPRequestHandler):
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        print(post_data.decode('utf-8'))

server_address = ('127.0.0.1', 5000)

httpd = http.server.HTTPServer(server_address, http.server.SimpleHTTPRequestHandler)
httpd.socket = SSLContext().wrap_socket(sock=httpd.socket,
                                        server_side=True,
                                        do_handshake_on_connect=False,
                                        suppress_ragged_eofs=True)
httpd.serve_forever()

出现的错误

  • 废弃警告:ssl.SSLContext()无协议参数已废弃,ssl.PROTOCOL_TLS已废弃
  • SSL握手错误:ssl.SSLError: [SSL: NO_SHARED_CIPHER] no shared cipher,更换多个端口仍无法解决

第二版代码及新问题

用户通过以下openssl命令生成证书和密钥:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

更新后的代码

import http.server
import ssl


class MyHandler(http.server.SimpleHTTPRequestHandler):
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        print(post_data.decode('utf-8'))


server_address = ('127.0.0.1', 5000)
httpd = http.server.HTTPServer(server_address, MyHandler)

context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile="cert.pem", keyfile="key.pem")

httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
httpd.serve_forever()

新问题

脚本卡在load_cert_chain步骤无响应


解决方案

1. 解决证书加载无响应问题

生成证书时若未设置密码,load_cert_chain可能会等待输入密码(即使无密码也可能触发),可明确指定无密码:

context.load_cert_chain(certfile="cert.pem", keyfile="key.pem", password=None)

或者重新生成证书时直接跳过密码设置:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

(-nodes参数表示不加密私钥,无需输入密码)

2. 实现接收一次请求后终止

修改服务器逻辑,处理完请求后立即关闭:

import http.server
import ssl


class MyHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        # Slack OAuth重定向为GET请求,需替换原POST逻辑
        print("Received OAuth redirect:", self.path)
        # 返回成功响应
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(b"Authorization received! You can close this window.")
        # 处理完成后关闭服务器
        self.server.shutdown()

server_address = ('127.0.0.1', 5000)
httpd = http.server.HTTPServer(server_address, MyHandler)

# 初始化TLS服务器上下文
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile="cert.pem", keyfile="key.pem", password=None)

httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
# 仅处理一次请求后退出
httpd.handle_request()

注意:Slack OAuth的重定向默认是GET请求,需实现do_GET方法而非do_POST

3. 验证证书有效性

若证书生成异常会导致加载失败,可通过以下命令验证:

# 验证证书内容
openssl x509 -in cert.pem -text -noout
# 验证私钥有效性
openssl rsa -in key.pem -check

关键注意事项

  • 必须使用ssl.PROTOCOL_TLS_SERVER作为SSL上下文协议,避免废弃警告
  • 确保证书和私钥文件与脚本在同一目录,或使用绝对路径指定
  • Slack OAuth重定向请求类型为GET,需对应调整请求处理方法

内容的提问来源于stack exchange,提问作者Mika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:06:06