下面是一个使用 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 接口:
- 登录并获取 Token:
curl -X POST -d '{"username": "test", "password": "password"}' -H 'Content-Type: application/json' http://localhost:8080/api/login
这将返回一个 JSON 响应,其中包含生成的 JWT Token。
- 调用受保护接口:
curl -H "Authorization: Bearer your_jwt_token" http://localhost:8080/api/protected
确保替换 your_jwt_token
为从登录接口获得的 Token。如果有效,你会看到对应的信息响应。
这样就完成了在 Go-Zero 框架中实现带有 JWT 校验的 API 接口!如果还有其他问题或需求,请随时询问!
内容由零声教学AI助手提供,问题来源于学员提问