Golang中如何使用Token处理Mux API
Golang中如何使用Token处理Mux API 我正在使用mux编写API,并希望为我的API使用令牌。该怎么做?
8 回复
我想使用一个bar token
这是哪种类型的令牌,JWT?还是其他类型?
我在查看一个关于API身份验证的旧教程……我认为JWT是目前最常用的方法。Bearer令牌只是一个在请求体中发送的生成令牌,但这不够安全。
我从未听说过这个。什么是"bar token"?你能提供一些相关信息的链接吗?你所说的"使用"它是什么意思?这种令牌是否包含认证信息?还是其他什么?
虽然这并非您问题的确切答案,但我刚发布的一篇文章确实展示了如何在OAuth2头部使用会话令牌进行API身份验证——https://www.calhoun.io/apis-are-just-web-applications
我建议首先阅读关于JWT的内容。然后查看jwt-go库。我写了一个简短示例,说明了我如何使用这个库生成和验证JWT。
只有在您理解了JWT的基本原理以及它是如何生成和验证的之后,才应该考虑如何将其集成到HTTP服务中。
在Golang中使用mux构建API时,可以通过中间件实现令牌验证。以下是一个完整的示例,展示如何创建JWT令牌验证中间件:
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/gorilla/mux"
)
// 定义JWT声明结构
type Claims struct {
Username string `json:"username"`
jwt.StandardClaims
}
// JWT密钥
var jwtKey = []byte("your-secret-key")
// 生成JWT令牌
func generateToken(username string) (string, error) {
expirationTime := time.Now().Add(24 * time.Hour)
claims := &Claims{
Username: username,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(jwtKey)
}
// JWT验证中间件
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
http.Error(w, "Authorization header required", http.StatusUnauthorized)
return
}
// 检查Bearer令牌格式
bearerToken := strings.Split(authHeader, " ")
if len(bearerToken) != 2 || bearerToken[0] != "Bearer" {
http.Error(w, "Invalid token format", http.StatusUnauthorized)
return
}
tokenString := bearerToken[1]
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if err != nil || !token.Valid {
http.Error(w, "Invalid token", http.StatusUnauthorized)
return
}
// 将用户信息添加到上下文
ctx := context.WithValue(r.Context(), "username", claims.Username)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
// 受保护的路由处理函数
func protectedHandler(w http.ResponseWriter, r *http.Request) {
username := r.Context().Value("username").(string)
response := map[string]string{
"message": fmt.Sprintf("Hello %s, you have access to protected resource", username),
}
json.NewEncoder(w).Encode(response)
}
// 登录处理函数
func loginHandler(w http.ResponseWriter, r *http.Request) {
var credentials struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := json.NewDecoder(r.Body).Decode(&credentials); err != nil {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}
// 简单的用户验证(生产环境应使用数据库验证)
if credentials.Username == "admin" && credentials.Password == "password" {
token, err := generateToken(credentials.Username)
if err != nil {
http.Error(w, "Error generating token", http.StatusInternalServerError)
return
}
response := map[string]string{
"token": token,
}
json.NewEncoder(w).Encode(response)
} else {
http.Error(w, "Invalid credentials", http.StatusUnauthorized)
}
}
func main() {
r := mux.NewRouter()
// 公开路由
r.HandleFunc("/login", loginHandler).Methods("POST")
// 受保护的路由
protected := r.PathPrefix("/api").Subrouter()
protected.Use(authMiddleware)
protected.HandleFunc("/protected", protectedHandler).Methods("GET")
fmt.Println("Server running on :8080")
log.Fatal(http.ListenAndServe(":8080", r))
}
这个示例包含以下关键部分:
- JWT令牌生成:
generateToken函数创建包含用户名的JWT令牌 - 认证中间件:
authMiddleware验证请求中的Bearer令牌 - 路由保护:使用mux的
Subrouter和Use方法应用中间件
使用示例:
# 获取令牌
curl -X POST -H "Content-Type: application/json" -d '{"username":"admin","password":"password"}' http://localhost:8080/login
# 访问受保护的路由
curl -H "Authorization: Bearer YOUR_TOKEN_HERE" http://localhost:8080/api/protected
对于简单的API密钥验证,可以使用更简单的中间件:
func apiKeyMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
apiKey := r.Header.Get("X-API-Key")
if apiKey != "your-api-key-here" {
http.Error(w, "Invalid API key", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
这种实现提供了基于令牌的API认证机制,可以根据具体需求调整令牌验证逻辑和密钥管理策略。

