ZBLOG

go-zero框架的 jwt-go

在Go-Zero框架中使用JWT进行身份验证是一个常见的需求。Go-Zero框架提供了一些内置的功能来处理JWT,简化了在API中实施身份验证的过程。下面是如何在Go-Zero框架中实现JWT身份验证的基本步骤。

1. 安装Go-Zero

首先,你需要安装Go-Zero。如果还没有安装,可以通过以下命令进行安装:

go get -u github.com/zeromicro/go-zero

2. 创建项目结构

假设你的项目结构如下:

your_project/
├── api/
│   └── your_api.api
├── logic/
│   ├── loginlogic.go
│   └── protectedlogic.go
├── middleware/
│   └── jwtmiddleware.go
├── model/
│   └── usermodel.go
└── main.go

3. 定义API文件

api/your_api.api文件中定义API接口:

syntax = "proto3";

package api;

service YourService {
    rpc Login(LoginRequest) returns (LoginResponse);
    rpc Protected(ProtectedRequest) returns (ProtectedResponse);
}

message LoginRequest {
    string username = 1;
    string password = 2;
}

message LoginResponse {
    string token = 1;
}

message ProtectedRequest {}

message ProtectedResponse {
    string message = 1;
}

4. 自动生成代码

使用以下命令生成代码:

goctl api protoc api/your_api.api --go_out=./ --go-grpc_out=./

5. 编写逻辑

登录逻辑(logic/loginlogic.go

在这里,我们将创建一个用户并返回JWT令牌:

package logic

import (
	"context"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/zeromicro/go-zero/core/logx"
	"your_project/api"
)

type LoginLogic struct {
	ctx context.Context
}

var secretKey = []byte("your_secret_key")

func (l *LoginLogic) Login(req *api.LoginRequest) (*api.LoginResponse, error) {
	// TODO: Validate username and password with your user model or database.
	if req.Username == "user" && req.Password == "pass" { // 示例用法,实际应验证数据库用户。
		token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
			"username": req.Username,
			"exp":      time.Now().Add(time.Hour * 72).Unix(),
		})

		tokenString, err := token.SignedString(secretKey)
		if err != nil {
			logx.Error(err)
			return nil, err
		}

		return &api.LoginResponse{Token: tokenString}, nil
	}
	return nil, nil // 应该返回相应错误提示。
}

受保护逻辑(logic/protectedlogic.go

确保用户具有有效的JWT才能访问此逻辑:

package logic

import (
    "context"

    "github.com/dgrijalva/jwt-go"
    "github.com/zeromicro/go-zero/core/logx"
    "your_project/api"
)

type ProtectedLogic struct {
	ctx context.Context
}

func (l *ProtectedLogic) Protected(req *api.ProtectedRequest) (*api.ProtectedResponse, error) {
	authHeader := l.ctx.Value("Authorization").(string)
	if authHeader == "" || len(authHeader) < 7 || authHeader[:6] != "Bearer" {
        return nil, errors.New("Unauthorized")
    }

	tokenString := authHeader[7:]
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
        return secretKey, nil 
    })

	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
        logx.Infof("User %s accessed protected route", claims["username"])
        return &api.ProtectedResponse{Message: "This is a protected route"}, nil 
    } else {
        return nil, errors.New("Unauthorized")
    }
}

6. 编写中间件(可选)

你可以编写一个中间件来解析JWT并将其添加到上下文中。这使得你可以轻松地从请求上下文中提取认证信息。

中间件 (middleware/jwtmiddleware.go)

package middleware

import (
    "net/http"

    "github.com/dgrijalva/jwt-go"
)

func JwtMiddleware(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
        authHeader := r.Header.Get("Authorization")
        if authHeader == "" || len(authHeader) < 7 || authHeader[:6] != "Bearer" {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return 
        }

        tokenString := authHeader[7:]
        
        _, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error){
            return []byte("your_secret_key"), nil 
        })
        
        if err != nil { 
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return 
        }

	    next(w,r)
	}
}

7. 主函数 (main.go)

最终,在主函数中设置路由和服务启动。

package main

import (
   "net/http"

   "github.com/zeromicro/go-zero/rest"
   . "your_project/api"
)

func main() {

	routes := rest.MustNewServer(rest.RestConf{})
	defer routes.Stop()

	routes.AddRoute(rest.Route{
	   Method: http.MethodPost,
	   Path: "/login",
	   Handler: JwtMiddleware(NewYourService().Login),
	  })
	
	routes.AddRoute(rest.Route{
	   Method: http.MethodGet,
	   Path: "/protected",
	   Handler: JwtMiddleware(NewYourService().Protected),
	  })

	routes.Start()
}

这样,你就完成了在 Go-Zero 框架下实现 JWT 身份验证 API 的基本示例。确保测试和进一步增强安全性,例如密码哈希、存储与用户模型等。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=22210

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?