添加QQ第三方登录
This commit is contained in:
parent
d1ab6e8c17
commit
e9e2805e70
|
|
@ -5,6 +5,7 @@
|
|||
<functions>
|
||||
<function importPath="net/http" name="NewRequest" />
|
||||
<function importPath="StuAcaWorksAI/worker" name="GetStackoverflowAccessTokenByCode" />
|
||||
<function importPath="StuAcaWorksAI/worker" name="GetQQAccessTokenByCode" />
|
||||
</functions>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
|
|
|
|||
|
|
@ -273,3 +273,48 @@ type StackoverflowUserInfoResponse struct {
|
|||
QuotaMax int `json:"quota_max"`
|
||||
QuotaRemaining int `json:"quota_remaining"`
|
||||
}
|
||||
|
||||
/*********************QQ**************************/
|
||||
type QQOAuthRequest struct {
|
||||
ClientID string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
Code string `json:"code"`
|
||||
RedirectURI string `json:"redirect_uri" `
|
||||
//'grant_type': 'authorization_code',
|
||||
GrantType string `json:"grant_type"`
|
||||
}
|
||||
|
||||
type QQOAuthTokenResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
type GetQQOpenIDResponse struct {
|
||||
ClientID string `json:"client_id"`
|
||||
OpenID string `json:"openid"`
|
||||
}
|
||||
|
||||
type QQUserInfoResponse struct {
|
||||
OpenID string `json:"openid"`
|
||||
Ret int `json:"ret"`
|
||||
Msg string `json:"msg"`
|
||||
IsLost int `json:"is_lost"`
|
||||
Nickname string `json:"nickname"`
|
||||
Gender string `json:"gender"`
|
||||
GenderType int `json:"gender_type"`
|
||||
Province string `json:"province"`
|
||||
City string `json:"city"`
|
||||
Year string `json:"year"`
|
||||
Figureurl string `json:"figureurl"`
|
||||
Figureurl1 string `json:"figureurl_1"`
|
||||
Figureurl2 string `json:"figureurl_2"`
|
||||
FigureurlQQ1 string `json:"figureurl_qq_1"`
|
||||
FigureurlQQ2 string `json:"figureurl_qq_2"`
|
||||
FigureurlQQ string `json:"figureurl_qq"`
|
||||
IsYellowVip string `json:"is_yellow_vip"`
|
||||
Vip string `json:"vip"`
|
||||
YellowVipLevel string `json:"yellow_vip_level"`
|
||||
Level string `json:"level"`
|
||||
IsYellowYearVip string `json:"is_yellow_year_vip"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ func DoThirdPartyCallBack(state *proto.ThirdPartyLoginState, code string) {
|
|||
case "gitee":
|
||||
DoGiteeCallBack(state, code)
|
||||
case "qq":
|
||||
// TODO
|
||||
DoQQCallBack(state, code)
|
||||
case "gogs":
|
||||
// TODO
|
||||
log.Println("DoThirdPartyCallBack gogs error:", state.Platform)
|
||||
|
|
@ -488,7 +488,6 @@ func DoThirdPartyCallBack(state *proto.ThirdPartyLoginState, code string) {
|
|||
case "facebook":
|
||||
DoFaceBookCallBack(state, code)
|
||||
case "stackoverflow":
|
||||
// TODO
|
||||
DoStackoverflowCallBack(state, code)
|
||||
default:
|
||||
log.Println("DoThirdPartyCallBack platform error:", state.Platform)
|
||||
|
|
@ -569,6 +568,7 @@ func DoStackoverflowCallBack(state *proto.ThirdPartyLoginState, code string) {
|
|||
userInfo = userInfoResp.Items[0]
|
||||
thirdPartyUserInfo := proto.ThirdPartyUserInfo{UserID: strconv.Itoa(userInfo.UserID), Name: userInfo.DisplayName, Avatar: userInfo.ProfileImage, Email: ""}
|
||||
HandleThirdPartyLoginStatusV2(state, &thirdPartyLoginStatus, &thirdPartyUserInfo)
|
||||
thirdPartyLoginStatus.Status = proto.SuccessCode
|
||||
} else {
|
||||
log.Println("get Stackoverflow user info is empty")
|
||||
thirdPartyLoginStatus.Status = proto.ParameterError
|
||||
|
|
@ -581,6 +581,34 @@ func DoStackoverflowCallBack(state *proto.ThirdPartyLoginState, code string) {
|
|||
worker.SetRedisWithExpire(state.UUID, string(thirdPartyLoginStatusStr), time.Minute*10)
|
||||
}
|
||||
|
||||
func DoQQCallBack(state *proto.ThirdPartyLoginState, code string) {
|
||||
var thirdPartyLoginStatus proto.ThirdPartyLoginStatus
|
||||
thirdPartyLoginStatus.Type = state.Platform
|
||||
//根据code获取Access Token
|
||||
tokenResp, err := worker.GetQQAccessTokenByCode(code, "https://www.ljsea.top/qq_callback.php", worker.QQClientID, worker.QQClientSecret)
|
||||
if tokenResp.AccessToken == "" {
|
||||
log.Println("get QQ access token is empty")
|
||||
thirdPartyLoginStatus.Status = proto.ParameterError
|
||||
} else {
|
||||
log.Println("get QQ access token:", tokenResp)
|
||||
//获取用户信息
|
||||
userInfo, err2 := worker.GetQQUserInfo(tokenResp.AccessToken)
|
||||
if err2 != nil {
|
||||
log.Println("get QQ user info error:", err)
|
||||
thirdPartyLoginStatus.Status = proto.ParameterError
|
||||
} else {
|
||||
log.Println("get QQ user info:", userInfo)
|
||||
thirdPartyUserInfo := proto.ThirdPartyUserInfo{UserID: userInfo.OpenID, Name: userInfo.Nickname, Avatar: userInfo.Figureurl, Email: ""}
|
||||
HandleThirdPartyLoginStatusV2(state, &thirdPartyLoginStatus, &thirdPartyUserInfo)
|
||||
thirdPartyLoginStatus.Status = proto.SuccessCode
|
||||
}
|
||||
}
|
||||
//更新redis中的第三方登录状态
|
||||
thirdPartyLoginStatusStr, _ := json.Marshal(thirdPartyLoginStatus)
|
||||
log.Println("do handle Stackoverflow callback success, third party login status:", string(thirdPartyLoginStatusStr))
|
||||
worker.SetRedisWithExpire(state.UUID, string(thirdPartyLoginStatusStr), time.Minute*10)
|
||||
}
|
||||
|
||||
// 国外服务器处理国内服务器要请求外网的请求
|
||||
func DoRequestToForeignServer(req *proto.OnlineServerReq) (proto.OutlineServerResp, error) {
|
||||
var resp proto.OutlineServerResp
|
||||
|
|
|
|||
|
|
@ -453,3 +453,63 @@ func GetStackoverflowUserInfo(accessToken string) (proto.StackoverflowUserInfoRe
|
|||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
const (
|
||||
QQClientID = "102774740"
|
||||
QQClientSecret = "iIfpkRuAF8rPn13q"
|
||||
)
|
||||
|
||||
func GetQQAccessTokenByCode(code string, redirectURI string, clientID string, clientSecret string) (proto.QQOAuthTokenResponse, error) {
|
||||
req := proto.QQOAuthRequest{
|
||||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
Code: code,
|
||||
RedirectURI: redirectURI,
|
||||
GrantType: "authorization_code",
|
||||
}
|
||||
var resp proto.QQOAuthTokenResponse
|
||||
url := "https://graph.qq.com/oauth2.0/token"
|
||||
url = fmt.Sprintf("%s?grant_type=%s&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s&fmt=json", url, req.GrantType, req.ClientID, req.ClientSecret, req.Code, req.RedirectURI)
|
||||
|
||||
err2, respBytes := DoGetRequest(url, nil)
|
||||
if err2 != nil {
|
||||
return resp, err2
|
||||
}
|
||||
err := json.Unmarshal(respBytes, &resp)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func GetQQUserInfo(accessToken string) (proto.QQUserInfoResponse, error) {
|
||||
var resp proto.QQUserInfoResponse
|
||||
|
||||
var openIDInfo proto.GetQQOpenIDResponse
|
||||
//先获取openid
|
||||
url := fmt.Sprintf("https://graph.qq.com/oauth2.0/me?access_token=%s&fmt=json", accessToken)
|
||||
err2, respBytes := DoGetRequest(url, nil)
|
||||
if err2 != nil {
|
||||
log.Println("GetQQUserInfo get openid err:", err2)
|
||||
return resp, err2
|
||||
}
|
||||
err := json.Unmarshal(respBytes, &openIDInfo)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
//如果openid获取成功,获取用户信息
|
||||
url = fmt.Sprintf("https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s&fmt=json", accessToken, QQClientID, openIDInfo.OpenID)
|
||||
err3, respBytes2 := DoGetRequest(url, nil)
|
||||
if err3 != nil {
|
||||
log.Println("GetQQUserInfo get user info err:", err2)
|
||||
return resp, err2
|
||||
}
|
||||
err = json.Unmarshal(respBytes2, &resp)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp.OpenID = openIDInfo.OpenID
|
||||
return resp, nil
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue