129 lines
3.1 KiB
Go
129 lines
3.1 KiB
Go
|
// 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)
|
||
|
}
|