123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- package outServer
- import (
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "net/http"
- "net/http/cookiejar"
- "net/url"
- "regexp"
- "strings"
- "sync"
- "time"
- "app.yhyue.com/moapp/jybase/common"
- "bp.jydev.jianyu360.cn/BaseService/gateway/core/router"
- "github.com/gogf/gf/v2/net/ghttp"
- "github.com/gogf/gf/v2/util/gconv"
- "golang.org/x/net/publicsuffix"
- )
- type sussBi struct {
- addr string
- loginAddr string
- user string
- pwd string
- Url *url.URL
- cookiePath string
- lastLogin time.Time
- loginLock *sync.RWMutex
- jar *cookiejar.Jar
- succbiJar *cookiejar.Jar
- prm *ParamReplaceManager
- singlePointUrl *regexp.Regexp
- }
- // 参数替换
- type ParamReplace struct {
- Replace []ParamReplaceSetting
- Match []ParamReplaceSetting
- }
- type ParamReplaceSetting struct {
- Key, Value string
- }
- type ParamReplaceManager struct {
- eqRouters map[string]*ParamReplace
- regexRouter map[*regexp.Regexp]*ParamReplace
- }
- func InitSussBi(config map[string]interface{}) (*sussBi, error) {
- address := gconv.String(config["addr"])
- user := gconv.String(config["user"])
- password := gconv.String(config["password"])
- paramReplace := gconv.Map(config["paramReplace"])
- cookiePath := gconv.String(config["cookiePath"])
- loginAddr := gconv.String(config["loginAddr"])
- if address == "" {
- return nil, fmt.Errorf("配置异常")
- }
- sussCookie, err := cookiejar.New(&cookiejar.Options{
- PublicSuffixList: publicsuffix.List,
- })
- if err != nil {
- return nil, fmt.Errorf("初始化cookie异常")
- }
- sussCookie2, err2 := cookiejar.New(&cookiejar.Options{
- PublicSuffixList: publicsuffix.List,
- })
- if err2 != nil {
- return nil, fmt.Errorf("初始化cookie异常")
- }
- prManager := &ParamReplaceManager{
- eqRouters: map[string]*ParamReplace{},
- regexRouter: map[*regexp.Regexp]*ParamReplace{},
- }
- for url, setting := range paramReplace {
- pr := &ParamReplace{}
- settingMap := gconv.Map(setting)
- if settingMap == nil || len(settingMap) == 0 {
- continue
- }
- if replaceMap := gconv.Map(settingMap["replace"]); replaceMap != nil && len(replaceMap) > 0 {
- for k, v := range replaceMap {
- pr.Replace = append(pr.Replace, ParamReplaceSetting{
- Key: k,
- Value: gconv.String(v),
- })
- }
- }
- replaceMap := gconv.Map(settingMap["match"])
- if replaceMap != nil && len(replaceMap) > 0 {
- for k, v := range replaceMap {
- pr.Match = append(pr.Match, ParamReplaceSetting{
- Key: k,
- Value: gconv.String(v),
- })
- }
- }
- if len(pr.Match) == 0 && len(pr.Replace) == 0 {
- continue
- }
- if regexp.QuoteMeta(url) == url {
- prManager.eqRouters[url] = pr
- } else {
- if reg, err := regexp.Compile(url); err == nil {
- prManager.regexRouter[reg] = pr
- }
- }
- }
- u, _ := url.Parse(address)
- return &sussBi{
- addr: address,
- user: user,
- Url: u,
- pwd: password,
- loginAddr: loginAddr,
- cookiePath: cookiePath,
- jar: sussCookie,
- lastLogin: time.Now(),
- loginLock: &sync.RWMutex{},
- succbiJar: sussCookie2,
- prm: prManager,
- singlePointUrl: regexp.MustCompile(gconv.String(config["singlePointUrl"])),
- }, nil
- }
- // AutoLogin 自动登录
- func (s *sussBi) AutoLogin() error {
- s.loginLock.Lock()
- defer s.loginLock.Unlock()
- if time.Now().Sub(s.lastLogin).Seconds() > 60 {
- client := &http.Client{
- Jar: s.succbiJar,
- }
- resp, err := client.Get(fmt.Sprintf("%s/succbi/?:user=%s&:password=%s", s.addr, s.user, s.pwd))
- if err != nil {
- return err
- }
- if !(resp.StatusCode == 302 || resp.StatusCode == 200) {
- return fmt.Errorf("自动登录异常")
- }
- s.succbiJar = s.jar
- s.lastLogin = time.Now()
- }
- return nil
- }
- // RequestLogin 装配登录状态
- func (s *sussBi) RequestLogin(r *ghttp.Request) error {
- if s.singlePointUrl.MatchString(r.RequestURI) {
- ctx := router.GetGContext(r.GetCtx())
- 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))
- c := &http.Cookie{
- Name: "BITOKEN",
- Value: md5Val,
- Path: "/",
- HttpOnly: false,
- MaxAge: 604800,
- Expires: time.Now().AddDate(0, 0, 7),
- }
- r.Request.AddCookie(c)
- log.Println(ctx.Sess.PositionId, "BITOKEN====", md5Val)
- //http.SetCookie(r.Response.ResponseWriter, c)
- } else {
- if strings.HasPrefix(r.URL.Path, "/succbi") {
- u, e := url.Parse(s.Url.String() + "/succbi")
- if e != nil {
- log.Println("RequestLogin url.Parse error", e)
- return e
- }
- log.Println("succbiJar----", u.Path, u.RequestURI(), s.succbiJar.Cookies(u))
- if cookies := s.succbiJar.Cookies(u); len(cookies) > 0 {
- log.Println("RequestLogin AddCookie", cookies[0])
- r.Request.AddCookie(cookies[0])
- }
- } else {
- if cookies := s.jar.Cookies(s.Url); len(cookies) > 0 {
- r.Request.AddCookie(cookies[0])
- }
- }
- }
- return nil
- }
- // CheckLoginOut 检测登录状态是否过期
- func (s *sussBi) CheckLoginOut(r *ghttp.Request) bool {
- if r.Response.Status == 401 {
- return true
- }
- return false
- }
- func (s *sussBi) Filter(r *ghttp.Request) error {
- ctx := router.GetGContext(r.GetCtx())
- if ctx.Sess.NewUid != 0 {
- replaceMap := map[string]interface{}{
- "jyUserId": ctx.Sess.PositionId,
- "jyUserPositionId": ctx.Sess.PositionId,
- "jyUserAccountId": ctx.Sess.AccountId,
- "jyEntPositionId": ctx.Sess.PositionId,
- "jyEntAccountId": ctx.Sess.EntAccountId,
- "jyUserName": ctx.Sess.UserName,
- "jyEntName": ctx.Sess.EntName,
- "jyEntId": ctx.Sess.EntId,
- "jyEntUserName": ctx.Sess.EntUserName,
- "jyEntUserId": ctx.Sess.EntUserId,
- }
- if r.Request.Method == http.MethodPost {
- bodyBytes, err := io.ReadAll(r.Request.Body)
- if err != nil {
- return err
- }
- if len(bodyBytes) > 0 {
- finalBytes := bodyBytes
- for k, v := range replaceMap {
- finalBytes = bytes.ReplaceAll(finalBytes, []byte(`"`+k+`"`), []byte(`"`+fmt.Sprint(v)+`"`))
- }
- r.ContentLength = gconv.Int64(len(finalBytes))
- r.Request.Header.Set("Content-Length", fmt.Sprintf("%d", len(finalBytes)))
- r.Request.Body = ioutil.NopCloser(bytes.NewReader(finalBytes))
- }
- } else if r.Request.Method == http.MethodGet {
- var prArr *ParamReplace
- if rule, ok := s.prm.eqRouters[r.URL.Path]; ok && rule != nil {
- prArr = rule
- } else {
- for reg, rule := range s.prm.regexRouter {
- if reg.MatchString(r.URL.Path) {
- prArr = rule
- break
- }
- }
- }
- if prArr != nil {
- if newValues, err := url.ParseQuery(r.URL.RawQuery); err == nil && len(newValues) > 0 {
- for _, replace := range prArr.Replace {
- if replace.Key != "" && replace.Value != "" && replaceMap[replace.Value] != nil {
- newValues[replace.Key] = []string{fmt.Sprintf("%v", replaceMap[replace.Value])}
- }
- }
- for _, match := range prArr.Match {
- if match.Key != "" && match.Value != "" {
- if arr := strings.Split(match.Key, "."); len(arr) == 2 && replaceMap[match.Value] != nil {
- if value, ok := newValues[arr[0]]; ok && len(value) > 0 {
- newValue := strings.ReplaceAll(value[0], arr[1], fmt.Sprintf("%v", replaceMap[match.Value]))
- newValues[arr[0]] = []string{newValue}
- }
- }
- }
- }
- r.URL.RawQuery = newValues.Encode()
- }
- }
- }
- }
- return nil
- }
|