ZBLOG

go-zero框架的 jwt-go

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

1. 安装Go-Zero

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

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

2. 创建项目结构

假设你的项目结构如下:

  1. your_project/
  2. ├── api/
  3. └── your_api.api
  4. ├── logic/
  5. ├── loginlogic.go
  6. └── protectedlogic.go
  7. ├── middleware/
  8. └── jwtmiddleware.go
  9. ├── model/
  10. └── usermodel.go
  11. └── main.go

3. 定义API文件

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

  1. syntax = "proto3";
  2. package api;
  3. service YourService {
  4. rpc Login(LoginRequest) returns (LoginResponse);
  5. rpc Protected(ProtectedRequest) returns (ProtectedResponse);
  6. }
  7. message LoginRequest {
  8. string username = 1;
  9. string password = 2;
  10. }
  11. message LoginResponse {
  12. string token = 1;
  13. }
  14. message ProtectedRequest {}
  15. message ProtectedResponse {
  16. string message = 1;
  17. }

4. 自动生成代码

使用以下命令生成代码:

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

5. 编写逻辑

登录逻辑(logic/loginlogic.go

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

  1. package logic
  2. import (
  3. "context"
  4. "time"
  5. "github.com/dgrijalva/jwt-go"
  6. "github.com/zeromicro/go-zero/core/logx"
  7. "your_project/api"
  8. )
  9. type LoginLogic struct {
  10. ctx context.Context
  11. }
  12. var secretKey = []byte("your_secret_key")
  13. func (l *LoginLogic) Login(req *api.LoginRequest) (*api.LoginResponse, error) {
  14. // TODO: Validate username and password with your user model or database.
  15. if req.Username == "user" && req.Password == "pass" { // 示例用法,实际应验证数据库用户。
  16. token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
  17. "username": req.Username,
  18. "exp": time.Now().Add(time.Hour * 72).Unix(),
  19. })
  20. tokenString, err := token.SignedString(secretKey)
  21. if err != nil {
  22. logx.Error(err)
  23. return nil, err
  24. }
  25. return &api.LoginResponse{Token: tokenString}, nil
  26. }
  27. return nil, nil // 应该返回相应错误提示。
  28. }

受保护逻辑(logic/protectedlogic.go

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

  1. package logic
  2. import (
  3. "context"
  4. "github.com/dgrijalva/jwt-go"
  5. "github.com/zeromicro/go-zero/core/logx"
  6. "your_project/api"
  7. )
  8. type ProtectedLogic struct {
  9. ctx context.Context
  10. }
  11. func (l *ProtectedLogic) Protected(req *api.ProtectedRequest) (*api.ProtectedResponse, error) {
  12. authHeader := l.ctx.Value("Authorization").(string)
  13. if authHeader == "" || len(authHeader) < 7 || authHeader[:6] != "Bearer" {
  14. return nil, errors.New("Unauthorized")
  15. }
  16. tokenString := authHeader[7:]
  17. token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
  18. return secretKey, nil
  19. })
  20. if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
  21. logx.Infof("User %s accessed protected route", claims["username"])
  22. return &api.ProtectedResponse{Message: "This is a protected route"}, nil
  23. } else {
  24. return nil, errors.New("Unauthorized")
  25. }
  26. }

6. 编写中间件(可选)

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

中间件 (middleware/jwtmiddleware.go)

  1. package middleware
  2. import (
  3. "net/http"
  4. "github.com/dgrijalva/jwt-go"
  5. )
  6. func JwtMiddleware(next http.HandlerFunc) http.HandlerFunc {
  7. return func(w http.ResponseWriter, r *http.Request) {
  8. authHeader := r.Header.Get("Authorization")
  9. if authHeader == "" || len(authHeader) < 7 || authHeader[:6] != "Bearer" {
  10. http.Error(w, "Unauthorized", http.StatusUnauthorized)
  11. return
  12. }
  13. tokenString := authHeader[7:]
  14. _, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error){
  15. return []byte("your_secret_key"), nil
  16. })
  17. if err != nil {
  18. http.Error(w, "Unauthorized", http.StatusUnauthorized)
  19. return
  20. }
  21. next(w,r)
  22. }
  23. }

7. 主函数 (main.go)

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

  1. package main
  2. import (
  3. "net/http"
  4. "github.com/zeromicro/go-zero/rest"
  5. . "your_project/api"
  6. )
  7. func main() {
  8. routes := rest.MustNewServer(rest.RestConf{})
  9. defer routes.Stop()
  10. routes.AddRoute(rest.Route{
  11. Method: http.MethodPost,
  12. Path: "/login",
  13. Handler: JwtMiddleware(NewYourService().Login),
  14. })
  15. routes.AddRoute(rest.Route{
  16. Method: http.MethodGet,
  17. Path: "/protected",
  18. Handler: JwtMiddleware(NewYourService().Protected),
  19. })
  20. routes.Start()
  21. }

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


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?