✨ add qq oauth2 login
This commit is contained in:
@@ -1 +1,160 @@
|
||||
package oauth_api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
ginI18n "github.com/gin-contrib/i18n"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"schisandra-cloud-album/common/result"
|
||||
"schisandra-cloud-album/global"
|
||||
)
|
||||
|
||||
type AuthQQme struct {
|
||||
ClientID string `json:"client_id"`
|
||||
OpenID string `json:"openid"`
|
||||
}
|
||||
|
||||
// GetQQRedirectUrl 获取登录地址
|
||||
// @Summary 获取QQ登录地址
|
||||
// @Description 获取QQ登录地址
|
||||
// @Tags 登录
|
||||
// @Produce json
|
||||
// @Success 200 {string} string "登录地址"
|
||||
// @Router /api/oauth/qq/get_url [get]
|
||||
func (OAuthAPI) GetQQRedirectUrl(c *gin.Context) {
|
||||
state := c.Query("state")
|
||||
clientId := global.CONFIG.OAuth.QQ.ClientID
|
||||
redirectURI := global.CONFIG.OAuth.QQ.RedirectURI
|
||||
url := "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=" + clientId + "&redirect_uri=" + redirectURI + "&state=" + state
|
||||
result.OkWithData(url, c)
|
||||
return
|
||||
}
|
||||
|
||||
// GetQQTokenAuthUrl 通过code获取token认证url
|
||||
func GetQQTokenAuthUrl(code string) string {
|
||||
clientId := global.CONFIG.OAuth.QQ.ClientID
|
||||
clientSecret := global.CONFIG.OAuth.QQ.ClientSecret
|
||||
redirectURI := global.CONFIG.OAuth.QQ.RedirectURI
|
||||
return fmt.Sprintf(
|
||||
"https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s",
|
||||
clientId, clientSecret, code, redirectURI,
|
||||
)
|
||||
}
|
||||
|
||||
// GetQQToken 获取 token
|
||||
func GetQQToken(url string) (*Token, error) {
|
||||
|
||||
// 形成请求
|
||||
var req *http.Request
|
||||
var err error
|
||||
if req, err = http.NewRequest(http.MethodGet, url, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("accept", "application/json")
|
||||
|
||||
// 发送请求并获得响应
|
||||
var httpClient = http.Client{}
|
||||
var res *http.Response
|
||||
if res, err = httpClient.Do(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 将响应体解析为 token,并返回
|
||||
var token Token
|
||||
if err = json.NewDecoder(res.Body).Decode(&token); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
// GetQQUserOpenID 获取用户 openid
|
||||
func GetQQUserOpenID(token *Token) (*AuthQQme, error) {
|
||||
|
||||
// 形成请求
|
||||
var userInfoUrl = "https://graph.qq.com/oauth2.0/me" // github用户信息获取接口
|
||||
var req *http.Request
|
||||
var err error
|
||||
if req, err = http.NewRequest(http.MethodGet, userInfoUrl, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("accept", "application/json")
|
||||
req.Header.Set("Authorization", fmt.Sprintf("token %s", token.AccessToken))
|
||||
// 发送请求并获取响应
|
||||
var client = http.Client{}
|
||||
var res *http.Response
|
||||
if res, err = client.Do(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 将响应体解析为 AuthQQme,并返回
|
||||
var authQQme AuthQQme
|
||||
if err = json.NewDecoder(res.Body).Decode(&authQQme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &authQQme, nil
|
||||
}
|
||||
|
||||
// GetQQUserUserInfo 获取用户信息
|
||||
func GetQQUserUserInfo(token *Token, openId string) (map[string]interface{}, error) {
|
||||
|
||||
clientId := global.CONFIG.OAuth.QQ.ClientID
|
||||
// 形成请求
|
||||
var userInfoUrl = "https://graph.qq.com/user/get_user_info??access_token=" + token.AccessToken + "&oauth_consumer_key=" + clientId + "&openid=" + openId
|
||||
var req *http.Request
|
||||
var err error
|
||||
if req, err = http.NewRequest(http.MethodGet, userInfoUrl, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("accept", "application/json")
|
||||
//req.Header.Set("Authorization", fmt.Sprintf("token %s", token.AccessToken))
|
||||
// 发送请求并获取响应
|
||||
var client = http.Client{}
|
||||
var res *http.Response
|
||||
if res, err = client.Do(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 将响应的数据写入 userInfo 中,并返回
|
||||
var userInfo = make(map[string]interface{})
|
||||
if err = json.NewDecoder(res.Body).Decode(&userInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
||||
|
||||
// QQCallback QQ登录回调
|
||||
// @Summary QQ登录回调
|
||||
// @Description QQ登录回调
|
||||
// @Tags 登录
|
||||
// @Produce json
|
||||
// @Router /api/oauth/qq/callback [get]
|
||||
func (OAuthAPI) QQCallback(c *gin.Context) {
|
||||
var err error
|
||||
// 获取 code
|
||||
var code = c.Query("code")
|
||||
if code == "" {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
return
|
||||
}
|
||||
// 通过 code, 获取 token
|
||||
var tokenAuthUrl = GetQQTokenAuthUrl(code)
|
||||
var token *Token
|
||||
if token, err = GetQQToken(tokenAuthUrl); err != nil {
|
||||
global.LOG.Error(err)
|
||||
return
|
||||
}
|
||||
authQQme, err := GetQQUserOpenID(token)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 通过token,获取用户信息
|
||||
var userInfo map[string]interface{}
|
||||
if userInfo, err = GetQQUserUserInfo(token, authQQme.OpenID); err != nil {
|
||||
global.LOG.Error(err)
|
||||
return
|
||||
}
|
||||
result.OkWithData(userInfo, c)
|
||||
return
|
||||
}
|
||||
|
Reference in New Issue
Block a user