
本文介绍如何在 Go 的标准 net/rpc/jsonrpc 服务中集成 JWT 实现细粒度授权,包括服务级准入控制和方法级权限校验,确保仅可信服务可调用、且仅能访问其被授权的 RPC 方法。
本文介绍如何在 go 的标准 `net/rpc/jsonrpc` 服务中集成 jwt 实现细粒度授权,包括服务级准入控制和方法级权限校验,确保仅可信服务可调用、且仅能访问其被授权的 rpc 方法。
在 Go 中构建内部服务间通信的 JSON-RPC 系统时,安全性不可忽视。与 HTTP REST 不同,JSON-RPC 协议本身不内置认证/授权机制,需由开发者在应用层显式实现。推荐采用 JWT(JSON Web Token) 作为授权凭证——它轻量、自包含、可签名验证,且天然支持声明式权限(如 allowed_methods: ["User.Get", "Order.Create"]),完美契合“限制服务调用范围”和“按方法授权”的双重需求。
✅ 基础架构设计思路
-
统一鉴权入口:所有受保护的 RPC 方法均接收一个
authToken string参数(或通过上下文注入,见后文进阶说明); -
JWT 签发与分发:提供专用登录方法(如
Auth.Login),客户端凭 API Key / 证书等完成身份核验后,服务端签发含权限声明的 JWT; -
方法级权限校验:每个 RPC 方法执行前,解析并验证 JWT 的签名、有效期,并检查
scope或permissions声明是否包含当前方法名。
? 示例:服务端 JWT 鉴权实现
使用 github.com/golang-jwt/jwt/v5(dgrijalva/jwt-go 的官方继任者,更安全、维护活跃):
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
package main
import (
"net"
"net/http"
"net/rpc"
"net/rpc/jsonrpc"
"time"
"github.com/golang-jwt/jwt/v5"
)
// 自定义 JWT 声明,支持方法白名单
type Claims struct {
jwt.RegisteredClaims
AllowedMethods []string `json:"allowed_methods"`
}
var jwtKey = []byte("your-32-byte-secret-key-here") // 生产环境请使用环境变量或密钥管理服务
func verifyToken(tokenStr string) (*Claims, error) {
token, err := jwt.ParseWithClaims(tokenStr, &Claims{}, func(t *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if err != nil {
return nil, err
}
if !token.Valid {
return nil, jwt.ErrSignatureInvalid
}
return token.Claims.(*Claims), nil
}
// RPC 方法示例:仅允许拥有 "Order.Create" 权限的令牌调用
type OrderService struct{}
func (s *OrderService) Create(r *struct {
AuthToken string `json:"auth_token"`
Item string `json:"item"`
}, resp *struct{ ID int }) error {
claims, err := verifyToken(r.AuthToken)
if err != nil {
return fmt.Errorf("authorization failed: %w", err)
}
// 检查权限
allowed := false
for _, m := range claims.AllowedMethods {
if m == "Order.Create" {
allowed = true
break
}
}
if !allowed {
return fmt.Errorf("permission denied: missing 'Order.Create' scope")
}
// 执行业务逻辑...
*resp = struct{ ID int }{ID: 123}
return nil
}
func main() {
rpc.Register(&OrderService{})
rpc.HandleHTTP()
listener, _ := net.Listen("tcp", ":8080")
http.Serve(listener, nil)
}
? 客户端调用示例(JSON-RPC 2.0 格式)
{
"jsonrpc": "2.0",
"method": "Order.Create",
"params": {
"auth_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"item": "book"
},
"id": 1
}
⚠️ 关键注意事项
- 令牌传输安全:JWT 必须通过 TLS(HTTPS / TLS-encrypted TCP)传输,禁止明文暴露;
-
密钥管理:
jwtKey应为强随机 32 字节密钥,避免硬编码,推荐使用os.Getenv("JWT_SECRET"); -
方法粒度控制:可在
Claims中定义allowed_methods []string、allowed_services []string或role string,按需组合判断; -
性能优化:对高频调用方法,可缓存已验证的
*Claims(以 token hash 为 key),避免重复解析; -
替代方案:若需更高安全性(如双向 TLS),可结合
net/rpc的http.Transport.TLSClientConfig实现 mTLS 认证,JWT 可作为补充权限层。
通过以上设计,你不仅实现了服务间调用的身份可信验证,更将权限精确到单个 RPC 方法,兼顾安全性与灵活性,是构建企业级内部 RPC 微服务的推荐实践。










