| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- package token
- import (
- "crypto/hmac"
- "crypto/sha256"
- "encoding/hex"
- "errors"
- "fmt"
- "mtp2_if/config"
- "mtp2_if/global/e"
- "mtp2_if/rediscli"
- "net/http"
- "runtime"
- "strings"
- "github.com/gin-gonic/gin"
- )
- // TouristToken 游客Token
- var TouristToken string = "c886a057f3d820d4dbc41473686c7c2d"
- // CheckToken Token校验
- func CheckToken(loginid string, token string, group string) (string, error) {
- key := ""
- if len(group) == 0 {
- key = fmt.Sprintf("monitor:online_loginid::%s", loginid)
- } else {
- key = fmt.Sprintf("monitor:online_loginid:%s:%s", loginid, group)
- }
- field := "Token"
- realToken, err := rediscli.GetRedisClient().HGet(key, field).Result()
- if err != nil {
- return "", err
- }
- if realToken != token {
- return "", errors.New("token is invalid")
- }
- // 获取UserID
- userID, err := rediscli.GetRedisClient().HGet(key, "UserID").Result()
- return userID, err
- }
- // Auth Token校验中间件
- func Auth() gin.HandlerFunc {
- return func(c *gin.Context) {
- // if config.SerCfg.GetDebugMode() {
- // c.Next()
- // return
- // }
- // windows下方便开发调试, 不做token校验
- if config.SerCfg.GetDebugMode() &&
- runtime.GOOS == "windows" {
- c.Next()
- return
- }
- var code int
- var data interface{}
- userID := ""
- code = e.SUCCESS
- token := c.GetHeader("Authorization")
- if token == "" {
- // Token缺失
- code = e.ERROR_AUTH_CHECK_TOKEN_FAIL
- } else {
- // 获取loginid
- s := strings.Split(token, "_")
- loginid := s[0]
- // 支持分组功能
- group := ""
- if len(s) == 3 {
- group = s[2]
- }
- var err error
- userID, err = CheckToken(loginid, token, group)
- if err != nil {
- // Token错误
- code = e.ERROR_AUTH_CHECK_TOKEN_FAIL
- }
- }
- // Token检验失败
- if code != e.SUCCESS {
- c.JSON(http.StatusUnauthorized, gin.H{
- "code": code,
- "msg": e.GetMsg(code),
- "data": data,
- })
- c.Abort()
- return
- }
- // FIXME: - 针对POST接口,应判断传入TOKEN对应的用户是否正确(比如判断UserID或AccountID是否对得上等),后期处理
- if c.Request.Method == "POST" {
- c.Set("requserid", userID)
- }
- if config.SerCfg.GetApiKeyMode() {
- timestamp := c.GetHeader("Timestamp")
- verification := c.GetHeader("Verification")
- if timestamp == "" || token == "" || verification == "" {
- c.JSON(http.StatusUnauthorized, gin.H{
- "code": e.ERROR,
- "msg": "缺少检验参数",
- "data": struct{}{},
- })
- c.Abort()
- return
- }
- s := fmt.Sprintf("%s%s", token, timestamp)
- hashed := hmac.New(sha256.New, []byte(config.SerCfg.WebCfg.ApiKey))
- hashed.Write([]byte(s))
- h := hex.EncodeToString(hashed.Sum(nil))
- if h == "" {
- c.JSON(http.StatusUnauthorized, gin.H{
- "code": e.ERROR,
- "msg": "接口检验失败",
- "data": struct{}{},
- })
- c.Abort()
- return
- }
- if h != verification {
- c.JSON(http.StatusUnauthorized, gin.H{
- "code": e.ERROR,
- "msg": "非法调用接口",
- "data": struct{}{},
- })
- c.Abort()
- return
- }
- }
- // Token检验成功
- c.Next()
- }
- }
- // AuthByHsby 游客鉴权
- func AuthByHsby() gin.HandlerFunc {
- return func(c *gin.Context) {
- // 包含accountID、accountIDs、userID和userIDs等参数需要走正常鉴权
- accountID := c.Query("accountID")
- accountIDs := c.Query("accountIDs")
- userID := c.Query("userID")
- userIDs := c.Query("userIDs")
- loginID := c.Query("loginID")
- if len(accountID) != 0 || len(accountIDs) != 0 || len(userID) != 0 || len(userIDs) != 0 || len(loginID) != 0 {
- realToken(c)
- return
- }
- var code int
- var data interface{}
- code = e.SUCCESS
- token := c.GetHeader("Authorization")
- if token == "" {
- // Token缺失
- code = e.ERROR_AUTH_CHECK_TOKEN_FAIL
- } else {
- // Token带下划线的走正常鉴权
- if strings.Contains(token, "_") {
- realToken(c)
- return
- }
- if token != TouristToken {
- // Token错误
- code = e.ERROR_AUTH_CHECK_TOKEN_FAIL
- }
- }
- // Token检验失败
- if code != e.SUCCESS {
- c.JSON(http.StatusUnauthorized, gin.H{
- "code": code,
- "msg": e.GetMsg(code),
- "data": data,
- })
- c.Abort()
- return
- }
- // Token检验成功
- c.Next()
- }
- }
- func realToken(c *gin.Context) {
- // if config.SerCfg.GetDebugMode() {
- // c.Next()
- // return
- // }
- var code int
- var data interface{}
- code = e.SUCCESS
- token := c.GetHeader("Authorization")
- if token == "" {
- // Token缺失
- code = e.ERROR_AUTH_CHECK_TOKEN_FAIL
- } else {
- // 获取loginid
- s := strings.Split(token, "_")
- loginid := s[0]
- // 支持分组功能
- group := ""
- if len(s) == 3 {
- group = s[2]
- }
- if _, err := CheckToken(loginid, token, group); err != nil {
- // Token错误
- code = e.ERROR_AUTH_CHECK_TOKEN_FAIL
- }
- }
- // Token检验失败
- if code != e.SUCCESS {
- c.JSON(http.StatusUnauthorized, gin.H{
- "code": code,
- "msg": e.GetMsg(code),
- "data": data,
- })
- c.Abort()
- return
- }
- // FIXME: - 针对POST接口,应判断传入TOKEN对应的用户是否正确(比如判断UserID或AccountID是否对得上等),后期处理
- // Token检验成功
- c.Next()
- return
- }
|