package gn import ( "bytes" "encoding/json" "errors" "eta_gn/eta_bridge/global" "fmt" "io" "net/http" "net/url" "strings" ) type AccessTokenResp struct { ErrResp `description:"报错响应"` AccessToken string `json:"access_token"` ExpiresIn int `json:"expires_in"` RefreshExpiresIn int `json:"refresh_expires_in"` RefreshToken string `json:"refresh_token"` TokenType string `json:"token_type"` NotBeforePolicy int `json:"not-before-policy"` SessionState string `json:"session_state"` //Error string `json:"error" description:"错误代码"` //ErrorDescription string `json:"error_description" description:"错误描述"` } type UserBaseInfoResp struct { ErrResp `description:"报错响应"` Sub string `json:"sub"` Name string `json:"name"` PreferredUsername string `json:"preferred_username"` GivenName string `json:"given_name"` FamilyName string `json:"family_name"` } // ErrResp // @Description: 错误信息返回 type ErrResp struct { Error string `json:"error" description:"错误代码"` ErrorDescription string `json:"error_description" description:"错误描述"` } // GetToken // @Description: 获取token信息 // @author: Roc // @datetime 2024-01-23 15:40:56 // @param code string // @return resp *AccessTokenResp // @return err error func GetToken(code string) (resp *AccessTokenResp, err error) { code = strings.TrimSpace(code) if code == "" { err = fmt.Errorf("code不可为空") return } //baseUrl := `%s?client_id=%s&client_secret=%s&redirect_uri=%s&code=%s&grant_type=authorization_code` baseUrl := global.CONFIG.Gn.AuthTokenApiUrl params := url.Values{} params.Add("client_id", global.CONFIG.Gn.AuthClientId) params.Add("client_secret", global.CONFIG.Gn.AuthClientSecret) params.Add("redirect_uri", global.CONFIG.Gn.AuthSSOCallbackUrl) params.Add("code", code) params.Add("grant_type", "authorization_code") //callbackUrl := url.QueryEscape(global.CONFIG.Gn.AuthSSOCallbackUrl) //fmt.Println("CallbackUrl: ", callbackUrl) //urlPath := fmt.Sprintf(baseUrl, global.CONFIG.Gn.AuthTokenApiUrl, global.CONFIG.Gn.AuthClientId, global.CONFIG.Gn.AuthClientSecret, callbackUrl, code) //fmt.Println("RequestUrl: ", urlPath) result, e := HttpPostAuth(baseUrl, params, "") //urlPath := fmt.Sprintf(`/idp/oauth2/getToken?client_id=%s&grant_type=authorization_code&code=%s&client_secret=%s`, global.CONFIG.Xiangyu.SystemCode, code, global.CONFIG.Xiangyu.UserKey) //result, e := HttpPostAuth(urlPath, ``, "") if e != nil { err = fmt.Errorf("统一认证请求失败, %v", e) return } fmt.Printf("Token RequestResult: %s\n", string(result)) // 解析响应结果 if e := json.Unmarshal(result, &resp); e != nil { err = fmt.Errorf("解析响应失败, %v", e) return } if resp.Error != "" { err = fmt.Errorf("Token请求失败, Err: %s, ErrMsg: %s ", resp.Error, resp.ErrorDescription) //err = errors.New(fmt.Sprintf("响应代码:%s,错误信息:%s", resp.ErrCode, resp.Msg)) return } return } // GetUserInfo // @Description: 获取用户信息 // @author: Roc // @datetime 2024-01-23 15:49:38 // @param token string // @return resp *UserBaseInfoResp // @return err error func GetUserInfo(code, token string) (resp *UserBaseInfoResp, err error) { code = strings.TrimSpace(code) token = strings.TrimSpace(token) if code == "" || token == "" { err = fmt.Errorf("Code和Token不可为空, Code: %s, Token: %s", code, token) return } baseUrl := global.CONFIG.Gn.AuthUserApiUrl params := url.Values{} params.Add("code", code) params.Add("access_token", token) //callbackUrl := url.QueryEscape(global.CONFIG.Gn.AuthSSOCallbackUrl) //fmt.Println("CallbackUrl: ", callbackUrl) //urlPath := fmt.Sprintf(baseUrl, global.CONFIG.Gn.AuthTokenApiUrl, global.CONFIG.Gn.AuthClientId, global.CONFIG.Gn.AuthClientSecret, callbackUrl, code) //fmt.Println("RequestUrl: ", urlPath) result, err := HttpPostAuth(baseUrl, params, "") //urlPath := fmt.Sprintf(`/idp/oauth2/getUserInfo?client_id=%s&access_token=%s`, global.CONFIG.Xiangyu.SystemCode, token) //result, err := HttpGetAuth(urlPath) if err != nil { return } fmt.Printf("UserInfoResult: %s\n", string(result)) // 解析响应结果 err = json.Unmarshal(result, &resp) if err != nil { return } if resp.Error != "" { err = fmt.Errorf("UserInfo请求失败, Err: %s, ErrMsg: %s ", resp.Error, resp.ErrorDescription) return } return } func HttpPostAuth(postUrl string, params url.Values, contentTypes ...string) ([]byte, error) { //if global.CONFIG.Xiangyu.UserAuthHost == `` { // return nil, errors.New("统一用户同步接口地址为空") //} // 请求地址 //postUrl := global.CONFIG.Xiangyu.UserAuthHost + urlPath //postUrl := urlPath //body := io.NopCloser(strings.NewReader(postData)) client := &http.Client{} req, err := http.NewRequest("POST", postUrl, bytes.NewBufferString(params.Encode())) //req, err := http.NewRequest("POST", postUrl, body) if err != nil { return nil, err } contentType := "application/x-www-form-urlencoded;charset=utf-8" if len(contentTypes) > 0 && contentTypes[0] != "" { contentType = contentTypes[0] } req.Header.Set("content-Type", contentType) resp, err := client.Do(req) if err != nil { return nil, err } defer func() { _ = resp.Body.Close() }() result, err := io.ReadAll(resp.Body) if err != nil { return nil, err } // 日志记录 postData := fmt.Sprintf("%v", params) global.FILE_LOG.Debug("统一认证:地址:" + postUrl + ";\n请求参数:" + postData + ";\n返回参数:" + string(result)) // 解析返回参数,判断是否是json if !json.Valid(result) { err = errors.New("返回参数不是json格式") } return result, err } // GetUserInfo // @Description: 获取用户信息 // @author: Roc // @datetime 2024-01-23 15:49:38 // @param token string // @return resp *UserBaseInfoResp // @return err error func GetUserInfoBySci(token string) (resp *UserBaseInfoResp, err error) { token = strings.TrimSpace(token) if token == "" { err = fmt.Errorf("Token不可为空,Token: %s", token) return } urlPath := fmt.Sprintf(`%s?token=%s`, `getuserinfo`, token) result, err := HttpGetAuth(urlPath) if err != nil { return } // 解析响应结果 err = json.Unmarshal(result, &resp) if err != nil { return } if resp.Error != "" { err = fmt.Errorf("UserInfo请求失败, Err: %s, ErrMsg: %s ", resp.Error, resp.ErrorDescription) return } return } func HttpGetAuth(urlPath string) ([]byte, error) { if global.CONFIG.Gn.AuthUserApiUrl == `` { return nil, errors.New("授权平台同步接口地址为空") } // 请求地址 getUrl := global.CONFIG.Gn.AuthUserApiUrl + urlPath client := &http.Client{} req, err := http.NewRequest("GET", getUrl, nil) if err != nil { return nil, err } resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() result, err := io.ReadAll(resp.Body) if err != nil { return nil, err } // 日志记录 global.FILE_LOG.Debug("授权平台:地址:" + getUrl + ";\n返回参数:" + string(result)) // 解析返回参数,判断是否是json if !json.Valid(result) { err = errors.New("返回参数不是json格式") } return result, err }