SussBi.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. package outServer
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "log"
  8. "net/http"
  9. "net/http/cookiejar"
  10. "net/url"
  11. "regexp"
  12. "strings"
  13. "sync"
  14. "time"
  15. "app.yhyue.com/moapp/jybase/common"
  16. "bp.jydev.jianyu360.cn/BaseService/gateway/core/router"
  17. "github.com/gogf/gf/v2/net/ghttp"
  18. "github.com/gogf/gf/v2/util/gconv"
  19. "golang.org/x/net/publicsuffix"
  20. )
  21. type sussBi struct {
  22. addr string
  23. loginAddr string
  24. user string
  25. pwd string
  26. Url *url.URL
  27. cookiePath string
  28. lastLogin time.Time
  29. loginLock *sync.RWMutex
  30. jar *cookiejar.Jar
  31. succbiJar *cookiejar.Jar
  32. prm *ParamReplaceManager
  33. singlePointUrl *regexp.Regexp
  34. }
  35. // 参数替换
  36. type ParamReplace struct {
  37. Replace []ParamReplaceSetting
  38. Match []ParamReplaceSetting
  39. }
  40. type ParamReplaceSetting struct {
  41. Key, Value string
  42. }
  43. type ParamReplaceManager struct {
  44. eqRouters map[string]*ParamReplace
  45. regexRouter map[*regexp.Regexp]*ParamReplace
  46. }
  47. func InitSussBi(config map[string]interface{}) (*sussBi, error) {
  48. address := gconv.String(config["addr"])
  49. user := gconv.String(config["user"])
  50. password := gconv.String(config["password"])
  51. paramReplace := gconv.Map(config["paramReplace"])
  52. cookiePath := gconv.String(config["cookiePath"])
  53. loginAddr := gconv.String(config["loginAddr"])
  54. if address == "" {
  55. return nil, fmt.Errorf("配置异常")
  56. }
  57. sussCookie, err := cookiejar.New(&cookiejar.Options{
  58. PublicSuffixList: publicsuffix.List,
  59. })
  60. if err != nil {
  61. return nil, fmt.Errorf("初始化cookie异常")
  62. }
  63. sussCookie2, err2 := cookiejar.New(&cookiejar.Options{
  64. PublicSuffixList: publicsuffix.List,
  65. })
  66. if err2 != nil {
  67. return nil, fmt.Errorf("初始化cookie异常")
  68. }
  69. prManager := &ParamReplaceManager{
  70. eqRouters: map[string]*ParamReplace{},
  71. regexRouter: map[*regexp.Regexp]*ParamReplace{},
  72. }
  73. for url, setting := range paramReplace {
  74. pr := &ParamReplace{}
  75. settingMap := gconv.Map(setting)
  76. if settingMap == nil || len(settingMap) == 0 {
  77. continue
  78. }
  79. if replaceMap := gconv.Map(settingMap["replace"]); replaceMap != nil && len(replaceMap) > 0 {
  80. for k, v := range replaceMap {
  81. pr.Replace = append(pr.Replace, ParamReplaceSetting{
  82. Key: k,
  83. Value: gconv.String(v),
  84. })
  85. }
  86. }
  87. replaceMap := gconv.Map(settingMap["match"])
  88. if replaceMap != nil && len(replaceMap) > 0 {
  89. for k, v := range replaceMap {
  90. pr.Match = append(pr.Match, ParamReplaceSetting{
  91. Key: k,
  92. Value: gconv.String(v),
  93. })
  94. }
  95. }
  96. if len(pr.Match) == 0 && len(pr.Replace) == 0 {
  97. continue
  98. }
  99. if regexp.QuoteMeta(url) == url {
  100. prManager.eqRouters[url] = pr
  101. } else {
  102. if reg, err := regexp.Compile(url); err == nil {
  103. prManager.regexRouter[reg] = pr
  104. }
  105. }
  106. }
  107. u, _ := url.Parse(address)
  108. return &sussBi{
  109. addr: address,
  110. user: user,
  111. Url: u,
  112. pwd: password,
  113. loginAddr: loginAddr,
  114. cookiePath: cookiePath,
  115. jar: sussCookie,
  116. lastLogin: time.Now(),
  117. loginLock: &sync.RWMutex{},
  118. succbiJar: sussCookie2,
  119. prm: prManager,
  120. singlePointUrl: regexp.MustCompile(gconv.String(config["singlePointUrl"])),
  121. }, nil
  122. }
  123. // AutoLogin 自动登录
  124. func (s *sussBi) AutoLogin() error {
  125. s.loginLock.Lock()
  126. defer s.loginLock.Unlock()
  127. if time.Now().Sub(s.lastLogin).Seconds() > 60 {
  128. client := &http.Client{
  129. Jar: s.succbiJar,
  130. }
  131. resp, err := client.Get(fmt.Sprintf("%s/succbi/?:user=%s&:password=%s", s.addr, s.user, s.pwd))
  132. if err != nil {
  133. return err
  134. }
  135. if !(resp.StatusCode == 302 || resp.StatusCode == 200) {
  136. return fmt.Errorf("自动登录异常")
  137. }
  138. s.succbiJar = s.jar
  139. s.lastLogin = time.Now()
  140. }
  141. return nil
  142. }
  143. // RequestLogin 装配登录状态
  144. func (s *sussBi) RequestLogin(r *ghttp.Request) error {
  145. if s.singlePointUrl.MatchString(r.RequestURI) {
  146. ctx := router.GetGContext(r.GetCtx())
  147. md5Val := common.GetMd5String(fmt.Sprintf("%s_%s_%d_%d_%d_%d_%d_%d_%s_%d_%s_%d", ctx.Sess.NickName, ctx.Sess.YyName, ctx.Sess.EntRole, ctx.Sess.EntNicheDis, ctx.Sess.PositionId, ctx.Sess.AccountId, ctx.Sess.EntAccountId, ctx.Sess.EntId, ctx.Sess.EntName, ctx.Sess.EntDeptId, ctx.Sess.EntUserName, ctx.Sess.EntUserId))
  148. c := &http.Cookie{
  149. Name: "BITOKEN",
  150. Value: md5Val,
  151. Path: "/",
  152. HttpOnly: false,
  153. MaxAge: 604800,
  154. Expires: time.Now().AddDate(0, 0, 7),
  155. }
  156. r.Request.AddCookie(c)
  157. log.Println(ctx.Sess.PositionId, "BITOKEN====", md5Val)
  158. //http.SetCookie(r.Response.ResponseWriter, c)
  159. } else {
  160. if strings.HasPrefix(r.URL.Path, "/succbi") {
  161. u, e := url.Parse(s.Url.String() + "/succbi")
  162. if e != nil {
  163. log.Println("RequestLogin url.Parse error", e)
  164. return e
  165. }
  166. log.Println("succbiJar----", u.Path, u.RequestURI(), s.succbiJar.Cookies(u))
  167. if cookies := s.succbiJar.Cookies(u); len(cookies) > 0 {
  168. log.Println("RequestLogin AddCookie", cookies[0])
  169. r.Request.AddCookie(cookies[0])
  170. }
  171. } else {
  172. if cookies := s.jar.Cookies(s.Url); len(cookies) > 0 {
  173. r.Request.AddCookie(cookies[0])
  174. }
  175. }
  176. }
  177. return nil
  178. }
  179. // CheckLoginOut 检测登录状态是否过期
  180. func (s *sussBi) CheckLoginOut(r *ghttp.Request) bool {
  181. if r.Response.Status == 401 {
  182. return true
  183. }
  184. return false
  185. }
  186. func (s *sussBi) Filter(r *ghttp.Request) error {
  187. ctx := router.GetGContext(r.GetCtx())
  188. if ctx.Sess.NewUid != 0 {
  189. replaceMap := map[string]interface{}{
  190. "jyUserId": ctx.Sess.PositionId,
  191. "jyUserPositionId": ctx.Sess.PositionId,
  192. "jyUserAccountId": ctx.Sess.AccountId,
  193. "jyEntPositionId": ctx.Sess.PositionId,
  194. "jyEntAccountId": ctx.Sess.EntAccountId,
  195. "jyUserName": ctx.Sess.UserName,
  196. "jyEntName": ctx.Sess.EntName,
  197. "jyEntId": ctx.Sess.EntId,
  198. "jyEntUserName": ctx.Sess.EntUserName,
  199. "jyEntUserId": ctx.Sess.EntUserId,
  200. }
  201. if r.Request.Method == http.MethodPost {
  202. bodyBytes, err := io.ReadAll(r.Request.Body)
  203. if err != nil {
  204. return err
  205. }
  206. if len(bodyBytes) > 0 {
  207. finalBytes := bodyBytes
  208. for k, v := range replaceMap {
  209. finalBytes = bytes.ReplaceAll(finalBytes, []byte(`"`+k+`"`), []byte(`"`+fmt.Sprint(v)+`"`))
  210. }
  211. r.ContentLength = gconv.Int64(len(finalBytes))
  212. r.Request.Header.Set("Content-Length", fmt.Sprintf("%d", len(finalBytes)))
  213. r.Request.Body = ioutil.NopCloser(bytes.NewReader(finalBytes))
  214. }
  215. } else if r.Request.Method == http.MethodGet {
  216. var prArr *ParamReplace
  217. if rule, ok := s.prm.eqRouters[r.URL.Path]; ok && rule != nil {
  218. prArr = rule
  219. } else {
  220. for reg, rule := range s.prm.regexRouter {
  221. if reg.MatchString(r.URL.Path) {
  222. prArr = rule
  223. break
  224. }
  225. }
  226. }
  227. if prArr != nil {
  228. if newValues, err := url.ParseQuery(r.URL.RawQuery); err == nil && len(newValues) > 0 {
  229. for _, replace := range prArr.Replace {
  230. if replace.Key != "" && replace.Value != "" && replaceMap[replace.Value] != nil {
  231. newValues[replace.Key] = []string{fmt.Sprintf("%v", replaceMap[replace.Value])}
  232. }
  233. }
  234. for _, match := range prArr.Match {
  235. if match.Key != "" && match.Value != "" {
  236. if arr := strings.Split(match.Key, "."); len(arr) == 2 && replaceMap[match.Value] != nil {
  237. if value, ok := newValues[arr[0]]; ok && len(value) > 0 {
  238. newValue := strings.ReplaceAll(value[0], arr[1], fmt.Sprintf("%v", replaceMap[match.Value]))
  239. newValues[arr[0]] = []string{newValue}
  240. }
  241. }
  242. }
  243. }
  244. r.URL.RawQuery = newValues.Encode()
  245. }
  246. }
  247. }
  248. }
  249. return nil
  250. }