// Package oauth ... // // Description : oauth ... // // Author : go_developer@163.com<张德满> // // Date : 2022/01/17 12:18 AM package oauth import ( "bytes" "encoding/json" "fmt" "io" "net/http" "net/url" "github.com/pkg/errors" "github.com/ddliu/go-httpclient" ) // NewOAuth 获取OAuth实例 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/17 12:19 AM func NewOAuth(cfg Config) *OAuth { return &OAuth{ cfg: cfg, } } // OAuth 管理 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/17 12:19 AM type OAuth struct { cfg Config } // GetAuthorizationPageURL 获取授权页面的URL // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/17 12:33 AM func (o *OAuth) GetAuthorizationPageURL(scope string, responseType string) string { return fmt.Sprintf( "%s%s?client_id=%s&redirect_uri=%s&scope=%s&response_type=%s", o.cfg.Domain, o.cfg.AuthorizationPageURI, o.cfg.ClientID, url.QueryEscape(o.cfg.CallbackURL), scope, responseType, ) } // ApplyAccessTokenByCode 通过code申请授权token // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/17 12:35 AM func (o *OAuth) ApplyAccessTokenByCode(code string, receiver interface{}) error { // OAuth 授权回调 parameter := map[string]string{ "code": code, "client_id": o.cfg.ClientID, "client_secret": o.cfg.ClientSecret, "grant_type": "authorization_code", } client := httpclient.NewHttpClient() client.WithHeader("Accept", "application/json") resp, err := client.Post(o.cfg.Domain+o.cfg.GetAccessTokenURI+"?grant_type=authorization_code", parameter) if nil != err { return err } if resp.StatusCode != http.StatusOK { return fmt.Errorf("【%v】%v", resp.StatusCode, resp.Status) } body, err := io.ReadAll(resp.Body) if nil != err { return errors.New("读取响应体失败: " + err.Error()) } decoder := json.NewDecoder(bytes.NewReader(body)) decoder.UseNumber() return decoder.Decode(receiver) } // ValidateAccessToken 验证授权token // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/17 12:43 AM func (o *OAuth) ValidateAccessToken(token string, receiver interface{}) error { if nil != o.cfg.FormatAccessTokenFunc { token = o.cfg.FormatAccessTokenFunc(token) } parameter := make(map[string]string) client := httpclient.NewHttpClient() client.WithHeader("Accept", "application/json") if o.cfg.UseAuthorization { client.WithHeader("Authorization", "token "+token) } else { parameter[o.cfg.AccessTokenKey] = token } resp, err := client.Get("https://git.zhangdeman.cn/api/v1/user?grant_type=authorization_code", parameter) if nil != err { return err } body, err := io.ReadAll(resp.Body) if nil != err { return errors.New("读取响应体失败 : " + err.Error()) } decoder := json.NewDecoder(bytes.NewReader(body)) decoder.UseNumber() return decoder.Decode(receiver) } // GetUserDetailByToken 根据 token 获取用户详情 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/17 12:55 AM func (o *OAuth) GetUserDetailByToken(token string, receiver interface{}) error { return o.ValidateAccessToken(token, receiver) }