ZBLOG

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

下面是使用 Go-Zero 创建一个健壮的 WebSocket 对话服务,并包含 JWT 认证的完整示例。

项目结构

首先,创建项目结构如下:

  1. websocket-chat/
  2. ├── main.go
  3. ├── jwt.go
  4. └── go.mod

1. 初始化 Go-Zero 项目

确保你已经安装了 Go-Zero。然后在项目目录中运行以下命令来初始化模块:

  1. go mod init websocket-chat

接下来,安装所需依赖项:

  1. go get -u github.com/zeromicro/go-zero
  2. go get -u github.com/gorilla/websocket
  3. go get -u github.com/dgrijalva/jwt-go

2. 编写 JWT 生成和验证逻辑 (jwt.go)

jwt.go 中实现 JWT 的生成和验证逻辑:

  1. package main
  2. import (
  3. "time"
  4. "github.com/dgrijalva/jwt-go"
  5. )
  6. var jwtSecret = []byte("your_secret_key")
  7. // GenerateToken 生成JWT Token
  8. func GenerateToken(username string) (string, error) {
  9. claims := jwt.StandardClaims{
  10. ExpiresAt: time.Now().Add(time.Hour * 24).Unix(),
  11. Issuer: username,
  12. }
  13. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  14. return token.SignedString(jwtSecret)
  15. }
  16. // JwtMiddleware JWT中间件,用于验证Token并解析用户信息。
  17. func JwtMiddleware(next http.HandlerFunc) http.HandlerFunc {
  18. return func(w http.ResponseWriter, r *http.Request) {
  19. token := r.Header.Get("Authorization")
  20. if token == "" {
  21. http.Error(w, "Unauthorized", http.StatusUnauthorized)
  22. return
  23. }
  24. tkn, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
  25. return jwtSecret, nil
  26. })
  27. if err != nil || !tkn.Valid {
  28. http.Error(w, "Unauthorized", http.StatusUnauthorized)
  29. return
  30. }
  31. // 如果需要,可以在这里提取用户信息并附加到请求上下文中
  32. next(w, r)
  33. }
  34. }

3. 实现 WebSocket 服务 (main.go)

main.go 文件中实现 WebSocket 服务以及登录功能:

  1. package main
  2. import (
  3. "net/http"
  4. "github.com/gorilla/websocket"
  5. "log"
  6. )
  7. type Client struct {
  8. conn *websocket.Conn
  9. send chan []byte
  10. }
  11. var clients = make(map[*Client]bool)
  12. var upgrader = websocket.Upgrader{
  13. CheckOrigin: func(r *http.Request) bool { return true },
  14. }
  15. func handleConnections(w http.ResponseWriter, r *http.Request) {
  16. conn, err := upgrader.Upgrade(w, r, nil)
  17. if err != nil {
  18. log.Println("Error during connection upgrade:", err)
  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. log.Println("Error reading message:", err)
  30. break
  31. }
  32. // 广播消息给所有连接的客户端。
  33. for c := range clients {
  34. select {
  35. case c.send <- message:
  36. default:
  37. close(c.send)
  38. delete(clients,c)
  39. }
  40. }
  41. }
  42. }
  43. func loginHandler(w http.ResponseWriter, r *http.Request) {
  44. username := r.FormValue("username")
  45. password := r.FormValue("password")
  46. if username == "user" && password == "pass" { // 简单示例,应替换为真实验证逻辑。
  47. token, _ := GenerateToken(username)
  48. w.Write([]byte(token))
  49. return
  50. }
  51. http.Error(w,http.StatusText(http.StatusUnauthorized),http.StatusUnauthorized)
  52. }
  53. func main() {
  54. http.HandleFunc("/ws", JwtMiddleware(handleConnections))
  55. http.HandleFunc("/login", loginHandler)
  56. go func() {
  57. for client := range clients {
  58. for msg := range client.send {
  59. if err := client.conn.WriteMessage(websocket.TextMessage,msg); err != nil {
  60. log.Println("Error writing message:", err)
  61. break
  62. }
  63. }
  64. }
  65. }()
  66. log.Fatal(http.ListenAndServe(":8080", nil))
  67. }

4. 测试 WebSocket 服务

启动你的应用程序:

  1. go run main.go jwt.go

使用 Postman 登录并获取 JWT

  1. 发起 POST 请求到 /login 接口,提供用户名和密码,例如: “` POST /login HTTP/1.1

username=user&password=pass

  1. 2. 如果成功,你将收到一个 JWT 响应。
  2. #### 使用 WebSocket 客户端进行连接
  3. 通过 WebSocket 客户端(如 JavaScript Postman)连接到 `/ws` 接口,同时添加 `Authorization` 标头以包含你从登录中获得的 JWT,例如:
  4. ```javascript
  5. const socket = new WebSocket('ws://localhost:8080/ws', [], { headers: {'Authorization': 'Bearer your_token_here'} });
  6. socket.onopen = function(event) {
  7. console.log('WebSocket is connected.');
  8. };
  9. socket.onmessage = function(event) {
  10. console.log('Message from server:', event.data);
  11. };

这样,你就成功搭建了一个简单但健壮的 WebSocket 对话服务,并且添加了 JWT 认证机制。在实际生产环境中,请确保加强安全性、完善错误处理和日志记录等。


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?