Go中实现RPC安全认证需在服务端拦截请求并验证身份,主要方式有:1. HTTP Header Token认证;2. 自定义Codec加签;3. TLS双向证书;4. 方法级权限控制。
在 Go 中实现 RPC 安全认证,核心是**在服务端拦截请求、验证身份,并拒绝未授权调用**。标准 net/rpc 本身不内置认证机制,需手动在传输层或逻辑层增强。下面给出实用、可落地的几种方式,兼顾简洁性与安全性。
若使用 http.ServeHTTP 暴露 RPC 服务(如 rpc.ServeHTTP),可在中间件中校验 token:
Authorization: Bearer 头中携带 JWT 或随机 tokenhttp.Handler 包裹默认 RPC handler,解析并校验 token 有效性(例如查 Redis 或验签名)http.StatusUnauthorized,RPC 请求不会进入实际方法示例关键片段:
handler := http.NewServeMux()
handler.Handle("/rpc", &authHandler{next: rpc.DefaultServer.HTTPHandler()})
type authHandler struct {
next http.Handler
}
func (h *authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
if !isValidToken(strings.TrimPrefix(auth, "Bearer ")) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
h.next.ServeHTTP(w, r)
}
在编解码层嵌入认证信息,让非法请求连解码都失败:
gob.Encoder/Decoder 或 json.Encoder/Decoder,在消息体外层添加 nonce + hmac 签名字段net/rpc 会自动终止该连接注意:此法对客户端强约束,需双方使用同一加签逻辑,适合可控环境(如微服务间通信)。
最彻底的方式——把认证下沉到 TCP 层,由 TLS 握手完成身份确认:
http.Server 时配置 TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
tls.Config.VerifyPeerCertificate 校验 CN 或扩展字段(如 service=payment)rpc.NewClient 需基于 http.Transport 构建,复用该 TLS 连接优势:零侵入业务逻辑,所有未持有效证书的连接在建立阶段就被拒,性能开销低且防中间人攻击。
即使网络层已认证,仍建议在
RPC 方法内部做最小权限检查:
userID、role)透传至方法上下文(可通过自定义结构体参数或 context.Context)if !canAccess(user, "AdminService.DeleteUser") { return errors.New("forbidden") }
不复杂但容易忽略:网络认证 ≠ 业务授权,二者应分层叠加。