You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在MCP Python SDK中结合SSE使用Bearer请求头实现客户端授权?

如何在MCP Python SDK中结合SSE使用Bearer请求头实现客户端授权?

嗨,我刚好在MCP Python SDK里折腾过类似的授权需求,给你一步步梳理下怎么结合SSE用Bearer请求头实现客户端授权哈!

首先得明确:SSE是基于HTTP长连接的,客户端发起SSE连接的第一步会发一个普通的HTTP请求握手,这个时候就会带上Authorization请求头,我们要做的就是在服务器端拦截这个请求,验证Bearer Token的合法性。

第一步:在服务器端添加Token验证的预处理钩子

MCP SDK提供了请求预处理的钩子,所有进来的请求(包括SSE的初始连接请求)都会经过这个钩子,我们可以在这里做Token校验:

from mcp.server import MCPServer
from mcp.types import RequestContext

def validate_bearer_token(context: RequestContext):
    # 从请求头里取出Authorization字段
    auth_header = context.request.headers.get("Authorization")
    
    # 先检查有没有这个头
    if not auth_header:
        context.response.status_code = 401
        context.response.body = "请提供Authorization请求头"
        return False
    
    # 检查是否是Bearer类型的Token格式
    if not auth_header.startswith("Bearer "):
        context.response.status_code = 401
        context.response.body = "授权格式错误,请使用Bearer方案"
        return False
    
    # 提取实际的Token字符串
    token = auth_header.split(" ")[1]
    
    # 这里替换成你自己的Token验证逻辑——比如查数据库、调用内部认证接口等
    # 举个简单的示例验证逻辑,你根据实际业务改就行
    def is_valid_token(token_str):
        # 这里写你的验证逻辑,比如判断token是否在有效列表里、签名是否合法等
        return token_str == "your-valid-token-123"
    
    if not is_valid_token(token):
        context.response.status_code = 403
        context.response.body = "Token无效或已过期"
        return False
    
    # 验证通过,继续处理后续请求
    return True

# 创建MCP服务器实例
server = MCPServer()

# 把验证钩子注册成全局预处理钩子,所有请求都会走这个校验
server.register_pre_request_hook(validate_bearer_token)

第二步:处理SSE业务逻辑

Token验证通过后,就可以正常处理SSE的流推送了,比如注册你的SSE服务方法:

@server.register_method("sse_authorized_stream")
def handle_authorized_sse_stream(context: RequestContext):
    # 这里已经通过Token验证了,直接处理SSE推送逻辑就行
    # 比如给客户端发事件
    context.response.sse.send_event("system_notice", data="已通过授权,开始推送SSE事件...")
    # 后续可以加定时推送、业务触发推送的逻辑

客户端这边的设置

就像你截图里的MCP Inspector那样,客户端在发起SSE请求的时候,要在请求头里带上Authorization: Bearer <你的有效Token>。不管是用MCP Inspector测试,还是自己写客户端代码,只要把这个请求头加上,服务器端的预处理钩子就能拿到Token并验证了。

一些小提醒

  • SSE是长连接,只要初始握手时Token验证通过,后续的事件推送就不需要重复校验了,所以初始的一次校验就够
  • 你的Token验证逻辑要尽量高效,毕竟每个SSE连接都会触发这个钩子,别用太耗时的操作拖慢连接建立速度
  • 如果你的Token有过期时间,得考虑Token过期后的处理:比如客户端检测到连接断开后,用新的Token重连,或者在SSE流里定期返回Token过期的事件提示客户端更新

备注:内容来源于stack exchange,提问作者Roman Gelembjuk

火山引擎 最新活动