ZBLOG

go-zero框架的 jwt-go api设计

在使用 go-zero 框架时,设计基于 JWT 的 API 通常包括用户注册、登录、JWT 生成和验证等功能。以下是一个示例 API 设计,用于实现这些功能。

示例 API 设计

  1. 依赖库: 确保已安装 jwt-go 库:
  1. go get github.com/dgrijalva/jwt-go
  1. API 路由: 使用 go-zero 的路由定义,创建如下几个路由:

    • POST /api/register: 用户注册
    • POST /api/login: 用户登录
    • GET /api/protected: 需要身份验证的保护资源
  2. 模型和请求参数: 首先定义一些数据结构来处理请求参数和响应结果。

  1. // user.go
  2. package model
  3. type User struct {
  4. ID int64 `json:"id"`
  5. Username string `json:"username"`
  6. Password string `json:"password"` // 请注意:真实应用中应存储哈希密码
  7. }
  8. type RegisterRequest struct {
  9. Username string `json:"username"`
  10. Password string `json:"password"`
  11. }
  12. type LoginRequest struct {
  13. Username string `json:"username"`
  14. Password string `json:"password"`
  15. }
  16. type LoginResponse struct {
  17. Token string `json:"token"`
  18. }
  1. 服务端逻辑
  1. package main
  2. import (
  3. "github.com/dgrijalva/jwt-go"
  4. "net/http"
  5. "time"
  6. )
  7. var jwtSecret = []byte("your_secret_key")
  8. func GenerateJWT(userId int64) (string, error) {
  9. claims := jwt.MapClaims{
  10. "user_id": userId,
  11. "exp": time.Now().Add(time.Hour * 72).Unix(),
  12. }
  13. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  14. return token.SignedString(jwtSecret)
  15. }
  16. // Mock database for demonstration purposes.
  17. var users = map[string]string{}
  18. func registerHandler(w http.ResponseWriter, r *http.Request) {
  19. var req RegisterRequest
  20. // Decode request body to req object (e.g., using json.NewDecoder)
  21. // Check if username already exists, and save the user data.
  22. users[req.Username] = req.Password // 不要在实际代码中明文存储密码,请使用哈希。
  23. httpx.OkJson(w, map[string]string{"message": "User registered successfully"})
  24. }
  25. func loginHandler(w http.ResponseWriter, r *http.Request) {
  26. var req LoginRequest
  27. // Decode request body to req object.
  28. if password, ok := users[req.Username]; ok && password == req.Password {
  29. token, err := GenerateJWT(int64(1)) // 实际情况应从数据库获取用户ID。
  30. if err != nil {
  31. http.Error(w, "Could not generate token", http.StatusInternalServerError)
  32. return
  33. }
  34. httpx.OkJson(w, LoginResponse{Token: token})
  35. } else {
  36. http.Error(w, "Invalid credentials", http.StatusUnauthorized)
  37. }
  38. }
  39. func protectedHandler(w http.ResponseWriter, r *http.Request) {
  40. tokenStr := r.Header.Get("Authorization")
  41. if tokenStr == "" {
  42. http.Error(w, "Authorization header is required", http.StatusUnauthorized)
  43. return
  44. }
  45. token, err := jwt.Parse(tokenStr[len("Bearer "):], func(token *jwt.Token) (interface{}, error) {
  46. if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
  47. return nil, ErrInvalidToken
  48. }
  49. return jwtSecret, nil
  50. })
  51. if err != nil || !token.Valid {
  52. http.Error(w, "Invalid token", http.StatusUnauthorized)
  53. return
  54. }
  55. w.Write([]byte("Welcome to the protected route!"))
  56. }
  1. 主函数与路由配置
  1. package main
  2. import (
  3. "github.com/zeromicro/go-zero/rest"
  4. )
  5. func main() {
  6. r := rest.NewServer()
  7. r.POST("/api/register", registerHandler)
  8. r.POST("/api/login", loginHandler)
  9. r.GET("/api/protected", AuthMiddleware(protectedHandler))
  10. r.Start()
  11. }

中间件函数(AuthMiddleware):

为了保护某些路由,需要创建一个中间件用于解析和验证 JWT。

  1. func AuthMiddleware(next rest.HandlerFunc) rest.HandlerFunc {
  2. return func(ctx *rest.Context) error {
  3. tokenStr := ctx.Header["Authorization"]
  4. if len(tokenStr) == 0 || !strings.HasPrefix(tokenStr[0], "Bearer ") {
  5. return rest.ErrUnauthorized
  6. }
  7. // 提取 Bearer 后面的部分作为令牌字符串。
  8. tokenStr = strings.TrimPrefix(tokenStr[0], "Bearer ")
  9. _, err := ParseJWT(tokenStr)
  10. if err != nil {
  11. return rest.ErrUnauthorized
  12. }
  13. return next(ctx)
  14. }
  15. }

总结

以上是一个简单的基于 JWT 身份验证的 API 示例,涵盖了用户注册、登录以及保护资源访问的基本流程。在真实场景中,你还需要加入错误处理、输入验证、安全性增强(如使用 HTTPS)、密码加密等措施。


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?