|
|
@@ -5,7 +5,9 @@ import (
|
|
|
"mtp20access/client"
|
|
|
"mtp20access/global"
|
|
|
commonRequest "mtp20access/model/common/request"
|
|
|
+ "mtp20access/model/common/response"
|
|
|
"mtp20access/model/quote/request"
|
|
|
+ "mtp20access/utils"
|
|
|
"net/http"
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
@@ -13,24 +15,57 @@ import (
|
|
|
"go.uber.org/zap"
|
|
|
)
|
|
|
|
|
|
-var upGrader = websocket.Upgrader{
|
|
|
- ReadBufferSize: 1000000,
|
|
|
- WriteBufferSize: 1000000,
|
|
|
- CheckOrigin: func(r *http.Request) bool {
|
|
|
- return true
|
|
|
- },
|
|
|
-}
|
|
|
-
|
|
|
// QuoteConn 终端连接WebSocket
|
|
|
func QuoteConn(c *gin.Context) (err error) {
|
|
|
// 获取请求账号信息
|
|
|
- s, exists := c.Get("claims")
|
|
|
- if !exists {
|
|
|
- err = errors.New("获取请求账号信息异常")
|
|
|
- global.M2A_LOG.Error(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
|
|
|
}
|
|
|
- claims := s.(*commonRequest.CustomClaims)
|
|
|
|
|
|
// 获取登录账户信息
|
|
|
client, exists := client.Clients[claims.SessionID]
|
|
|
@@ -40,13 +75,26 @@ func QuoteConn(c *gin.Context) (err error) {
|
|
|
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.SetWebSocket(ws)
|
|
|
|
|
|
return
|