Golang中WebSocket握手时遇到403错误如何解决
Golang中WebSocket握手时遇到403错误如何解决

我正在尝试在Go和Angular中使用socket.io,但遇到了以下错误:
gin.SetMode(gin.ReleaseMode)
router := gin.Default()
//CORS
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:4200"},
AllowMethods: []string{"PUT", "PATCH", "POST", "GET", "DELETE"},
AllowHeaders: []string{"Origin", "X-Requested-With", "Content-Type", "Cache-
Control", "Pragma", "Authorization", "Accept", "Accept-Encoding"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
// AllowOriginFunc: func(origin string) bool {
// return origin == "*"
// },
MaxAge: 12 * time.Hour,
}))
server, err := socketio.NewServer(nil)
if err != nil {
log.Fatal(err)
}
server.OnConnect("/", func(s socketio.Conn) error {
s.SetContext("")
fmt.Println("connected:", s.ID())
return nil
})
server.OnEvent("/", "message", func(s socketio.Conn, msg string) {
fmt.Println("notice:", msg)
s.Emit("response", "Nuevo Pedido")
})
server.OnEvent("/chat", "msg", func(s socketio.Conn, msg string) string {
s.SetContext(msg)
return "recv " + msg
})
server.OnDisconnect("/", func(s socketio.Conn, msg string) {
fmt.Println("closed", msg)
server.OnEvent("/", "bye", func(s socketio.Conn) string {
last := s.Context(https://bit.ly/2D5lSqU).(string)
server.OnDisconnect("/", func(s socketio.Conn, msg string) {
fmt.Println("closed", msg)
s.Emit("bye", last)
s.Close()
return last
})
server.OnDisconnect("/", func(s socketio.Conn, msg string) {
fmt.Println("closed", msg)
})
router.GET("/socket.io/*any", gin.WrapH(server))
router.POST("/socket.io/*any", gin.WrapH(server))
// router.Handle("WSS", "/socket.io", []gin.HandlerFunc{SocketHandler})
//SERVER PORT
router.Run(":5000")
更多关于Golang中WebSocket握手时遇到403错误如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang中WebSocket握手时遇到403错误如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中使用socket.io库处理WebSocket连接时遇到403错误,通常是由于跨域(CORS)配置或握手验证问题导致的。以下是针对您代码的具体解决方案:
主要问题分析
403错误通常发生在WebSocket握手阶段,主要有以下几个原因:
- CORS配置不完整,缺少WebSocket相关头部
- socket.io服务器配置需要调整
- 握手验证失败
解决方案
1. 修复CORS配置,添加WebSocket相关头部
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:4200"},
AllowMethods: []string{"PUT", "PATCH", "POST", "GET", "DELETE", "OPTIONS"},
AllowHeaders: []string{
"Origin",
"X-Requested-With",
"Content-Type",
"Cache-Control",
"Pragma",
"Authorization",
"Accept",
"Accept-Encoding",
"Sec-WebSocket-Key",
"Sec-WebSocket-Version",
"Sec-WebSocket-Extensions",
"Sec-WebSocket-Protocol",
"Upgrade",
"Connection",
},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}))
2. 配置socket.io服务器允许跨域
// 创建socket.io服务器时添加CORS配置
server, err := socketio.NewServer(&engineio.Options{
Transports: []string{"websocket", "polling"},
AllowUpgrades: []string{"websocket"},
PingTimeout: 60000,
PingInterval: 25000,
Cors: &engineio.Cors{
AllowOriginFunc: func(origin string) bool {
return origin == "http://localhost:4200"
},
AllowCredentials: true,
},
})
if err != nil {
log.Fatal(err)
}
3. 添加OPTIONS方法处理预检请求
// 在路由中添加OPTIONS方法处理
router.OPTIONS("/socket.io/*any", func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "http://localhost:4200")
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
c.Header("Access-Control-Allow-Credentials", "true")
c.Status(200)
})
4. 完整修复后的代码示例
package main
import (
"fmt"
"log"
"time"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
socketio "github.com/googollee/go-socket.io"
"github.com/googollee/go-socket.io/engineio"
)
func main() {
gin.SetMode(gin.ReleaseMode)
router := gin.Default()
// CORS配置
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:4200"},
AllowMethods: []string{"PUT", "PATCH", "POST", "GET", "DELETE", "OPTIONS"},
AllowHeaders: []string{
"Origin",
"X-Requested-With",
"Content-Type",
"Cache-Control",
"Pragma",
"Authorization",
"Accept",
"Accept-Encoding",
"Sec-WebSocket-Key",
"Sec-WebSocket-Version",
"Sec-WebSocket-Extensions",
"Sec-WebSocket-Protocol",
"Upgrade",
"Connection",
},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}))
// 处理OPTIONS预检请求
router.OPTIONS("/socket.io/*any", func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "http://localhost:4200")
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
c.Header("Access-Control-Allow-Credentials", "true")
c.Status(200)
})
// 创建socket.io服务器
server, err := socketio.NewServer(&engineio.Options{
Transports: []string{"websocket", "polling"},
AllowUpgrades: []string{"websocket"},
PingTimeout: 60000,
PingInterval: 25000,
Cors: &engineio.Cors{
AllowOriginFunc: func(origin string) bool {
return origin == "http://localhost:4200"
},
AllowCredentials: true,
},
})
if err != nil {
log.Fatal(err)
}
// 连接事件处理
server.OnConnect("/", func(s socketio.Conn) error {
s.SetContext("")
fmt.Println("connected:", s.ID())
return nil
})
server.OnEvent("/", "message", func(s socketio.Conn, msg string) {
fmt.Println("notice:", msg)
s.Emit("response", "Nuevo Pedido")
})
server.OnEvent("/chat", "msg", func(s socketio.Conn, msg string) string {
s.SetContext(msg)
return "recv " + msg
})
server.OnDisconnect("/", func(s socketio.Conn, msg string) {
fmt.Println("closed", msg)
})
// 路由配置
router.GET("/socket.io/*any", gin.WrapH(server))
router.POST("/socket.io/*any", gin.WrapH(server))
// 启动服务器
fmt.Println("Server starting on :5000")
router.Run(":5000")
}
5. Angular客户端连接示例
// 在Angular中连接时确保配置正确
import { io } from 'socket.io-client';
const socket = io('http://localhost:5000', {
transports: ['websocket', 'polling'],
withCredentials: true,
extraHeaders: {
"Authorization": "Bearer your-token-if-needed"
}
});
socket.on('connect', () => {
console.log('Connected to server');
});
socket.on('response', (data) => {
console.log('Response:', data);
});
关键点说明
- CORS头部:必须包含WebSocket特定的头部(Sec-WebSocket-*等)
- OPTIONS预检:WebSocket握手前会发送OPTIONS请求,需要正确处理
- socket.io配置:需要在创建服务器时配置CORS选项
- 凭证传递:确保
AllowCredentials: true和客户端withCredentials: true匹配
这些修改应该能解决您的403错误问题。如果问题仍然存在,请检查浏览器开发者工具的网络面板,查看具体的请求和响应头部信息。

