Go 鉴权 SDK

Preview

快速开始

在应用后端挂载 token 路由。路由验证已登录用户,向 Nuva 获取访问 token,并返回给前端 SDK。

Go
issuer, err := nuvaauth.NewClient(nuvaauth.ClientConfig{
    BaseURL:      apiBaseURL,
    ServiceToken: os.Getenv("NUVA_SERVICE_TOKEN"),
})
if err != nil { return err }

handler, err := nuvaauth.NewAuthHandler(issuer, resolveNuvaGrant)
if err != nil { return err }

mux.Handle("/api/nuva-token", handler)

将 apiBaseURL 设为接入配置中的 Nuva 服务地址。nuvaauth 为 Go SDK 包别名。通过环境变量或服务端密钥管理配置 NUVA_SERVICE_TOKEN。

/api/nuva-token 是应用后端的路由路径,可按项目约定调整。前端 getAccessToken 回调应请求相同路径。

服务配置

字段类型要求
BaseURLstringNuva 授权服务地址,来自接入配置。
ServiceTokenstring客户级 Nuva 服务凭证,仅保存在后端。
issuerTokenIssuer由 NewClient 创建的授权服务客户端。
resolveResolveGrant从请求中验证登录身份,并返回用户授权信息。

NewAuthHandler 要求 issuer 和 resolve 均非 nil。初始化失败时返回 error。使用 cookie 登录的应用应为此路由启用现有 CSRF 校验。

登录适配

实现 ResolveGrant。从已验证的登录会话中读取用户 ID,从服务端授权策略中读取 UI skills 和权限。

Go
func resolveNuvaGrant(r *http.Request) (nuvaauth.ClientTokenRequest, error) {
    user, err := appauth.CurrentUser(r)
    if errors.Is(err, appauth.ErrNoSession) {
        return nuvaauth.ClientTokenRequest{}, nuvaauth.ErrUnauthenticated
    }
    if err != nil { return nuvaauth.ClientTokenRequest{}, err }

    grant, err := accessPolicy.NuvaAccess(r.Context(), user.ID)
    if errors.Is(err, accessPolicy.ErrDenied) {
        return nuvaauth.ClientTokenRequest{}, nuvaauth.ErrForbidden
    }
    if err != nil { return nuvaauth.ClientTokenRequest{}, err }

    return nuvaauth.ClientTokenRequest{
        UserID:      user.ID,
        UISkills:    grant.UISkills,
        Permissions: grant.Permissions,
    }, nil
}

将 appauth 和 accessPolicy 替换为项目的登录与授权模块。不要从浏览器请求体直接读取有效用户身份或权限。

返回错误HTTP 状态
ErrUnauthenticated401
ErrForbidden403
其他 error500

Token 申请参数

Go
type ClientTokenRequest struct {
    UserID      string          `json:"userId"`
    UISkills    []DefinitionRef `json:"uiSkills"`
    Permissions json.RawMessage `json:"permissions"`
}

type DefinitionRef struct {
    ID       string `json:"id"`
    Revision string `json:"revision"`
}
字段说明
UserID客户内的用户唯一标识。必须来自已验证的登录会话,且不能为空。
UISkills允许使用的 UI skill ID 和版本。空列表或 nil 仅使用平台默认工具。
Permissions服务端授权配置的 JSON。使用接入配置指定的格式,不能为空或 null。
DefinitionRef.ID已注册的 UI skill ID。
DefinitionRef.Revision该 UI skill 的版本。

Nuva 校验申请范围后签发用户 token。浏览器使用返回的 token 连接前端 SDK。

HTTP 响应

使用 POST /api/nuva-token,携带应用的登录 cookie 或用户凭证。该路由不需要 JSON 请求体。

成功响应

HTTP
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: no-store

{
  "token": "<Nuva user access token>",
  "expiresAt": "2026-10-12T18:15:00Z"
}
字段类型说明
tokenstringNuva 用户访问 token。
expiresAtstringRFC 3339 格式的到期时间。

错误响应

HTTP
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Cache-Control: no-store

{
  "error": { "code": "UNAUTHENTICATED" }
}
HTTP 状态error.code含义
401UNAUTHENTICATED未登录或登录已失效。
403FORBIDDEN应用策略或 Nuva 拒绝授权。
405METHOD_NOT_ALLOWED使用了 POST 以外的方法。
500AUTH_CONFIGURATION_ERROR登录适配器出错,或授权数据无效。
502NUVA_AUTH_UNAVAILABLENuva 授权请求失败,或返回的 token 为空、已过期。

响应包含 Cache-Control: no-store。前端应保留失败状态,并按应用的登录和错误处理流程处理。

API 参考

Go
type ClientConfig struct {
    BaseURL      string
    ServiceToken string
}

func NewClient(ClientConfig) (TokenIssuer, error)
func NewAuthHandler(TokenIssuer, ResolveGrant) (http.Handler, error)

type TokenIssuer interface {
    CreateClientToken(context.Context, ClientTokenRequest) (ClientToken, error)
}

type ResolveGrant func(*http.Request) (ClientTokenRequest, error)

type ClientToken struct {
    Token     string    `json:"token"`
    ExpiresAt time.Time `json:"expiresAt"`
}
方法返回值
NewClient(config)TokenIssuer;初始化失败时返回 error。
CreateClientToken(ctx, request)ClientToken,包含 Token 和 ExpiresAt;授权失败时返回 error。
NewAuthHandler(issuer, resolve)http.Handler;缺少依赖时返回 error。

HTTP handler 参考代码 · 前端 token 接入示例

搜索当前文档