ZBLOG

用 go-zero 写一个健壮的websocket对话服务 包含jwt认证

使用 Go-Zero 创建一个健壮的 WebSocket 对话服务并实现 JWT 认证的基本步骤如下:

1. 安装 Go-Zero

首先,确保你已经安装了 Go-Zero。可以通过以下命令安装:

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

2. 初始化项目

使用 go-zero 命令行工具来初始化项目。

  1. go-ctl new websocket-chat
  2. cd websocket-chat

3. 编写 JWT 中间件

创建一个文件 jwt.go 用于实现 JWT 的生成和验证:

  1. package middleware
  2. import (
  3. "net/http"
  4. "time"
  5. "github.com/dgrijalva/jwt-go"
  6. "github.com/zeromicro/go-zero/rest/httpx"
  7. )
  8. var jwtSecret = []byte("your_secret_key")
  9. // GenerateToken 生成JWT Token
  10. func GenerateToken(username string) (string, error) {
  11. claims := jwt.StandardClaims{
  12. ExpiresAt: time.Now().Add(time.Hour * 24).Unix(),
  13. Issuer: username,
  14. }
  15. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  16. return token.SignedString(jwtSecret)
  17. }
  18. // JwtMiddleware JWT中间件,用于验证Token
  19. func JwtMiddleware(next http.HandlerFunc) http.HandlerFunc {
  20. return func(w http.ResponseWriter, r *http.Request) {
  21. token := r.Header.Get("Authorization")
  22. if token == "" {
  23. http.Error(w, "Unauthorized", http.StatusUnauthorized)
  24. return
  25. }
  26. tkn, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
  27. return jwtSecret, nil
  28. })
  29. if err != nil || !tkn.Valid {
  30. http.Error(w, "Unauthorized", http.StatusUnauthorized)
  31. return
  32. }
  33. next(w, r)
  34. }
  35. }

4. 创建 WebSocket 服务

main.go 文件中创建 WebSocket 服务:

  1. package main
  2. import (
  3. "net/http"
  4. "github.com/gorilla/websocket"
  5. "github.com/zeromicro/go-zero/rest/httpx"
  6. "your_project/middleware" // 替换为你的项目路径
  7. )
  8. var upgrader = websocket.Upgrader{
  9. CheckOrigin: func(r *http.Request) bool { return true },
  10. }
  11. type Client struct {
  12. conn *websocket.Conn
  13. send chan []byte
  14. }
  15. var clients = make(map[*Client]bool)
  16. func handleConnections(w http.ResponseWriter, r *http.Request) {
  17. conn, err := upgrader.Upgrade(w, r, nil)
  18. if err != nil {
  19. return
  20. }
  21. client := &Client{conn: conn, send: make(chan []byte)}
  22. defer func() {
  23. conn.Close()
  24. delete(clients, client)
  25. }()
  26. for {
  27. _, message, err := conn.ReadMessage()
  28. if err != nil {
  29. break
  30. }
  31. // 广播消息给所有连接的客户端。
  32. for c := range clients {
  33. select {
  34. case c.send <- message:
  35. default:
  36. close(c.send)
  37. delete(clients,c)
  38. }
  39. }
  40. }
  41. }
  42. func main() {
  43. http.HandleFunc("/ws", middleware.JwtMiddleware(handleConnections))
  44. go func() {
  45. for client := range clients {
  46. for msg := range client.send {
  47. if err := client.conn.WriteMessage(websocket.TextMessage,msg); err != nil {
  48. break
  49. }
  50. }
  51. }
  52. }()
  53. err := http.ListenAndServe(":8080", nil)
  54. if err != nil { panic(err) }
  55. }

5. 用户登录和获取 Token

你可能还需要一个登录接口,允许用户通过用户名和密码进行身份验证并获取 JWT。例如,你可以在 main.go 中添加如下代码:

  1. func loginHandler(w http.ResponseWriter, r *http.Request) {
  2. username := r.FormValue("username")
  3. password := r.FormValue("password")
  4. if username == "user" && password == "pass" { // 简单示例,应替换为真实验证逻辑。
  5. token, _ := middleware.GenerateToken(username)
  6. w.Write([]byte(token))
  7. return
  8. }
  9. http.Error(w,http.StatusText(http.StatusUnauthorized),http.StatusUnauthorized)
  10. }

然后将该处理程序添加到路由中:

  1. http.HandleFunc("/login", loginHandler)

6. 测试 WebSocket 服务

启动应用程序并测试。使用 Postman 或类似工具请求 /login 接口以获得 JWT,并在请求 /ws 时将其包含在 Authorization 标头中。

请注意,以上代码是一个简化示例,具体生产环境应考虑更复杂的错误处理、日志记录以及安全性等因素。同时,请确保引入必要的依赖项,例如 github.com/gorilla/websocketgithub.com/dgrijalva/jwt-go


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?