添加QQ第三方登录
This commit is contained in:
parent
d1ab6e8c17
commit
e9e2805e70
|
|
@ -5,6 +5,7 @@
|
||||||
<functions>
|
<functions>
|
||||||
<function importPath="net/http" name="NewRequest" />
|
<function importPath="net/http" name="NewRequest" />
|
||||||
<function importPath="StuAcaWorksAI/worker" name="GetStackoverflowAccessTokenByCode" />
|
<function importPath="StuAcaWorksAI/worker" name="GetStackoverflowAccessTokenByCode" />
|
||||||
|
<function importPath="StuAcaWorksAI/worker" name="GetQQAccessTokenByCode" />
|
||||||
</functions>
|
</functions>
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
</profile>
|
</profile>
|
||||||
|
|
|
||||||
|
|
@ -273,3 +273,48 @@ type StackoverflowUserInfoResponse struct {
|
||||||
QuotaMax int `json:"quota_max"`
|
QuotaMax int `json:"quota_max"`
|
||||||
QuotaRemaining int `json:"quota_remaining"`
|
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":
|
case "gitee":
|
||||||
DoGiteeCallBack(state, code)
|
DoGiteeCallBack(state, code)
|
||||||
case "qq":
|
case "qq":
|
||||||
// TODO
|
DoQQCallBack(state, code)
|
||||||
case "gogs":
|
case "gogs":
|
||||||
// TODO
|
// TODO
|
||||||
log.Println("DoThirdPartyCallBack gogs error:", state.Platform)
|
log.Println("DoThirdPartyCallBack gogs error:", state.Platform)
|
||||||
|
|
@ -488,7 +488,6 @@ func DoThirdPartyCallBack(state *proto.ThirdPartyLoginState, code string) {
|
||||||
case "facebook":
|
case "facebook":
|
||||||
DoFaceBookCallBack(state, code)
|
DoFaceBookCallBack(state, code)
|
||||||
case "stackoverflow":
|
case "stackoverflow":
|
||||||
// TODO
|
|
||||||
DoStackoverflowCallBack(state, code)
|
DoStackoverflowCallBack(state, code)
|
||||||
default:
|
default:
|
||||||
log.Println("DoThirdPartyCallBack platform error:", state.Platform)
|
log.Println("DoThirdPartyCallBack platform error:", state.Platform)
|
||||||
|
|
@ -569,6 +568,7 @@ func DoStackoverflowCallBack(state *proto.ThirdPartyLoginState, code string) {
|
||||||
userInfo = userInfoResp.Items[0]
|
userInfo = userInfoResp.Items[0]
|
||||||
thirdPartyUserInfo := proto.ThirdPartyUserInfo{UserID: strconv.Itoa(userInfo.UserID), Name: userInfo.DisplayName, Avatar: userInfo.ProfileImage, Email: ""}
|
thirdPartyUserInfo := proto.ThirdPartyUserInfo{UserID: strconv.Itoa(userInfo.UserID), Name: userInfo.DisplayName, Avatar: userInfo.ProfileImage, Email: ""}
|
||||||
HandleThirdPartyLoginStatusV2(state, &thirdPartyLoginStatus, &thirdPartyUserInfo)
|
HandleThirdPartyLoginStatusV2(state, &thirdPartyLoginStatus, &thirdPartyUserInfo)
|
||||||
|
thirdPartyLoginStatus.Status = proto.SuccessCode
|
||||||
} else {
|
} else {
|
||||||
log.Println("get Stackoverflow user info is empty")
|
log.Println("get Stackoverflow user info is empty")
|
||||||
thirdPartyLoginStatus.Status = proto.ParameterError
|
thirdPartyLoginStatus.Status = proto.ParameterError
|
||||||
|
|
@ -581,6 +581,34 @@ func DoStackoverflowCallBack(state *proto.ThirdPartyLoginState, code string) {
|
||||||
worker.SetRedisWithExpire(state.UUID, string(thirdPartyLoginStatusStr), time.Minute*10)
|
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) {
|
func DoRequestToForeignServer(req *proto.OnlineServerReq) (proto.OutlineServerResp, error) {
|
||||||
var resp proto.OutlineServerResp
|
var resp proto.OutlineServerResp
|
||||||
|
|
|
||||||
|
|
@ -453,3 +453,63 @@ func GetStackoverflowUserInfo(accessToken string) (proto.StackoverflowUserInfoRe
|
||||||
}
|
}
|
||||||
return resp, nil
|
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