| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- package trade
- import (
- "errors"
- "mtp20access/client"
- "mtp20access/global"
- "mtp20access/model/common/response"
- "mtp20access/utils"
- "net/http"
- "github.com/gin-gonic/gin"
- "github.com/gorilla/websocket"
- "go.uber.org/zap"
- )
- // TradeConn 终端连接WebSocket
- func TradeConn(c *gin.Context) (err error) {
- // 获取请求账号信息
- // s, exists := c.Get("claims")
- // if !exists {
- // err = errors.New("获取请求账号信息异常")
- // global.M2A_LOG.Error(err.Error())
- // return
- // }
- // claims := s.(*commonRequest.CustomClaims)
- // 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
- token := c.Request.Header.Get("Sec-WebSocket-Protocol")
- if token == "" {
- response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
- c.Abort()
- return
- }
- j := utils.NewJWT()
- // parseToken 解析token包含的信息
- claims, err := j.ParseToken(token)
- if err != nil {
- if err == utils.ErrTokenExpired {
- response.FailWithCodeAndDetail(gin.H{"reload": true}, response.ERROR_TOKEN_EXPIRED, "授权已过期", c)
- // c.Abort()
- return
- }
- response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
- // c.Abort()
- return
- }
- // 从Redis获取登录信息
- loginMap, err := j.GetRedisLogin(claims.LoginID, claims.Group)
- if err != nil {
- response.FailWithCodeAndDetail(gin.H{"reload": true}, response.ERROR_TOKEN_OTHER_LOGIN, "您的帐户异地登陆或令牌失效", c)
- // c.Abort()
- return
- }
- // 判断Token是否有效
- if redisToken, isHas := loginMap["token"]; isHas {
- if redisToken != token {
- response.FailWithCodeAndDetail(gin.H{"reload": true}, response.ERROR_TOKEN_OTHER_LOGIN, "您的帐户异地登陆或令牌失效", c)
- // c.Abort()
- return
- }
- } else {
- response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
- // c.Abort()
- return
- }
- // 获取登录账户信息
- client, exists := client.Clients[claims.SessionID]
- if !exists {
- err = errors.New("获取登录账户信息异常")
- global.M2A_LOG.Error(err.Error(), zap.Any("SessionID", claims.SessionID))
- return
- }
- // 需要注意的是,如果前端通过websocket连接时指定了Sec-WebSocket-Protocol,后端接收到连接后,必须原封不动的将Sec-WebSocket-Protocol头信息返回给前端,否则连接会抛出异常。
- // c.Header("Sec-WebSocket-Protocol", token)
- // c.String(200, "ok")
- // 将http连接升级为websocket连接
- upGrader := websocket.Upgrader{
- ReadBufferSize: 1000000,
- WriteBufferSize: 1000000,
- CheckOrigin: func(r *http.Request) bool {
- return true
- },
- //将获取的参数放进这个数组
- Subprotocols: []string{token},
- }
- ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
- if err != nil {
- err = errors.New("连接错误")
- global.M2A_LOG.Error("将http连接升级为websocket连接失败", zap.Any("err", err))
- return
- }
- client.SetTradeWebSocket(ws)
- return
- }
|