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 认证

  1. syntax = "v1"
  2. type LoginReq {
  3. Username string `json:"username"`
  4. Password string `json:"password"`
  5. }
  6. type LoginResp {
  7. ID string `json:"id"`
  8. Name string `json:"name"`
  9. }
  10. type UserInfoReq {
  11. ID string `json:"id"`
  12. }
  13. type UserInfoResp {
  14. Name string `json:"name"`
  15. }
  16. service user-api {
  17. @handler login
  18. post /user/login (LoginReq) returns (LoginResp)
  19. }
  20. @server (
  21. jwt: Auth // 开启 jwt 认证
  22. )
  23. service user-api {
  24. @handler userInfo
  25. post /user/info (UserInfoReq) returns (UserInfoResp)
  26. }

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

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

  • config.go
  • routes.go
  1. package config
  2. import "github.com/zeromicro/go-zero/rest"
  3. type Config struct {
  4. rest.RestConf
  5. Auth struct {// JWT 认证需要的密钥和过期时间配置
  6. AccessSecret string
  7. AccessExpire int64
  8. }
  9. }

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

  1. // Code generated by goctl. DO NOT EDIT.
  2. package handler
  3. import (
  4. "net/http"
  5. "go-zero-demo/user/internal/svc"
  6. "github.com/zeromicro/go-zero/rest"
  7. )
  8. func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
  9. server.AddRoutes(
  10. []rest.Route{
  11. {
  12. Method: http.MethodPost,
  13. Path: "/user/login",
  14. Handler: loginHandler(serverCtx),
  15. },
  16. },
  17. )
  18. server.AddRoutes(
  19. []rest.Route{
  20. {
  21. Method: http.MethodPost,
  22. Path: "/user/info",
  23. Handler: userInfoHandler(serverCtx),
  24. },
  25. },
  26. rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
  27. )
  28. }

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

JWT - 图1注意

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