ZBLOG

go-zero 实现jwt 校验token 的api接口 包含api文件

下面是一个使用 Go-Zero 框架实现 JWT 校验的 API 接口示例,包括完整的 API 文件和相关代码结构。这个示例将涵盖 API 的定义、JWT 中间件以及基本的登录逻辑以生成 JWT。

1. 创建项目结构

你可以创建一个新的 Go 项目,目录结构如下:

my-go-zero-project/
├── api/
│   └── user.api
├── config/
│   └── etc.yaml
├── middleware/
│   └── jwt.go
├── model/
│   └── user_model.go
├── main.go
└── auth.go

2. 创建 user.api 文件

api/user.api 文件中定义接口。

syntax = "proto3";

package api;

service User {
    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;
}

3. 创建用户模型(model/user_model.go)

我们可以创建一个简单的用户模型来模拟用户数据。

// model/user_model.go

package model

type User struct {
	Username string
	Password string // 注意:实际应用中请不要明文存储密码,应进行加密处理。
}

// 模拟用户登录检查的方法
func ValidateUser(username, password string) bool {
	// 在这里,我们假设只有一个用户名为 "test" 的用户,密码为 "password"
	return username == "test" && password == "password"
}

4. 实现 JWT 中间件(middleware/jwt.go)

创建一个 JWT 中间件,用于校验 token。

// middleware/jwt.go

package middleware

import (
	"context"
	"net/http"
	"strings"

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

var jwtSecret = []byte("your_secret_key") // 替换为你的密钥

func JwtMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		tokenString := r.Header.Get("Authorization")
		
		if tokenString == "" || !strings.HasPrefix(tokenString, "Bearer ") {
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}

		tokenString = strings.TrimPrefix(tokenString, "Bearer ")

		claims := &jwt.StandardClaims{}
		token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
			return jwtSecret, nil
		})

		if err != nil || !token.Valid {
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}

        ctx := context.WithValue(r.Context(), "userID", claims.Subject)
        r = r.WithContext(ctx)

        next.ServeHTTP(w, r)
    })
}

5. 实现身份验证逻辑(auth/auth.go)

创建用于生成 JWT 的函数。

// auth/auth.go

package auth

import (
    "time"

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

var jwtSecret = []byte("your_secret_key") // 替换为你的密钥

func GenerateToken(username string) (string, error) {
	expirationTime := time.Now().Add(24 * time.Hour)

	clams := &jwt.StandardClaims{
	    Subject:   username,
	    ExpiresAt: expirationTime.Unix(),
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, clams)
	return token.SignedString(jwtSecret)
}

6. 实现主程序(main.go)

最后,在主程序中设置 HTTP 路由,并实现 API 的处理逻辑。

// main.go

package main

import (
    "encoding/json"
    "net/http"

    _ "github.com/go-sql-driver/mysql" // MySQL 驱动,根据需要引入数据库驱动。
    "github.com/gorilla/mux"
    
    "./api"      // 修改为你实际的路径 
    "./middleware" // 修改为你实际的路径 
    "./auth"       // 修改为你实际的路径 
    "./model"      // 修改为你实际的路径 
)

func main() {
	r := mux.NewRouter()

	r.HandleFunc("/api/login", loginHandler).Methods("POST")
	r.Handle("/api/protected", middleware.JwtMiddleware(http.HandlerFunc(protectedHandler))).Methods("GET")

	http.ListenAndServe(":8080", r)
}

// 登录处理函数,生成JWT Token。
func loginHandler(w http.ResponseWriter, r *http.Request) {
	var req api.LoginRequest
    
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.Username == "" || req.Password == "" {
        http.Error(w, "Invalid request", http.StatusBadRequest)
        return
    }

	if !model.ValidateUser(req.Username, req.Password) {  
    	http.Error(w, "Invalid credentials", http.StatusUnauthorized)
    	return  
   }
   
	token, err := auth.GenerateToken(req.Username)
	if err != nil {  
    	http.Error(w,"Could not generate token",http.StatusInternalServerError)  
    	return  
   } 

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(api.LoginResponse{Token: token})
}

// 受保护的路由处理函数。
func protectedHandler(w http.ResponseWriter, r *http.Request) {
	userID := r.Context().Value("userID") // 从上下文获取用户信息(如果有的话)
	message := fmt.Sprintf("This is a protected route for user: %s.", userID.(string))
	w.Write([]byte(message))
}

7. 启动服务器并测试接口

现在,你可以启动服务器:

go run main.go middleware/jwt.go auth/auth.go model/user_model.go api/user.api # 根据需要调整命令格式.

测试 API 接口:

  1. 登录并获取 Token
curl -X POST -d '{"username": "test", "password": "password"}' -H 'Content-Type: application/json' http://localhost:8080/api/login

这将返回一个 JSON 响应,其中包含生成的 JWT Token。

  1. 调用受保护接口
curl -H "Authorization: Bearer your_jwt_token" http://localhost:8080/api/protected 

确保替换 your_jwt_token 为从登录接口获得的 Token。如果有效,你会看到对应的信息响应。

这样就完成了在 Go-Zero 框架中实现带有 JWT 校验的 API 接口!如果还有其他问题或需求,请随时询问!


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?