Skip to main content

JWT

概述

在 go-zero 中,我们通过 api 语言来声明 HTTP 服务,然后通过 goctl 生成 HTTP 服务代码,在之前我们系统性的介绍了 API 规范

在 HTTP 服务开发中,服务认证也是经常会用到的一个功能,本文档将介绍如何在 api 文件中声明中间件。

JWT

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用间传递声明式信息。它是一种基于JSON的轻量级的身份验证和授权机制,用于在客户端和服务器之间安全地传输信息。

更多关于 jwt 的文档请参考

  1. 《JSON Web Tokens》
  2. 《JWT 认证》

我们来看一下在 api 文件中如何声明开启 jwt 认证

syntax = "v1"

type LoginReq {
Username string `json:"username"`
Password string `json:"password"`
}

type LoginResp {
ID string `json:"id"`
Name string `json:"name"`
}

type UserInfoReq {
ID string `json:"id"`
}

type UserInfoResp {
Name string `json:"name"`
}

service user-api {
@handler login
post /user/login (LoginReq) returns (LoginResp)
}

@server (
jwt: Auth // 开启 jwt 认证
)
service user-api {
@handler userInfo
post /user/info (UserInfoReq) returns (UserInfoResp)
}

在上文中,我们通过在 @server 中来通过 jwt 关键字声明了开启 jwt 认证,且该 jwt 认证仅对其对应的路由有用,如上文中 jwt 仅对 /user/info 生效,对 /user/login 是不生效的,我们使用 Auth 来作为 jwt 的值,其在经过 goctl 进行代码生成后会转成 对应 jwt 配置。

下面简单看一下生成的 jwt 代码:

package config

import "github.com/zeromicro/go-zero/rest"

type Config struct {
rest.RestConf
Auth struct {// JWT 认证需要的密钥和过期时间配置
AccessSecret string
AccessExpire int64
}
}

Config 结构体中的 Auth 字段就是我们通过在 api 语法文件中声明的值,这是代码生成后的结果。

在上文中,我们可以看到,我们声明的 jwt 其实在生成代码后通过 rest.WithJwt 来声明进行 jwt 认证了。

注意

代码生成后的 jwt 认证,框架只做了服务端逻辑,对于 jwt token 的生成及 refresh token 仍需要开发者自行实现。

载体信息获取

jwt 通常可以携带一些自定义信息,比如 server 端生成 jwt key 时添加了 custom-key 值,go-zero 在解析后会将所有载体放到 context 中,开发者可以 通过如下示例获取载体信息。

func (l *UserInfoLogic) UserInfo(req *types.UserInfoReq) (resp *types.UserInfoResp, err error) {
// 获取 jwt 载体信息
value:=l.ctx.Value("custom-key")
return
}