diff --git a/handler/tool.go b/handler/tool.go index 47604a2..2b80747 100644 --- a/handler/tool.go +++ b/handler/tool.go @@ -818,6 +818,15 @@ func GetThirdPartyAuthUrl(c *gin.Context) { baseUri := proto.GoogleAuthorizeBaseUrl respUrl = fmt.Sprintf("%s?%s", baseUri, params.Encode()) respUrl = fmt.Sprintf("%s&redirect_uri=%s&scope=%s", respUrl, redirectURL, scope) + case "facebook": + params := url.Values{} + params.Add("client_id", worker.FacebookClientID) + params.Add("redirect_uri", "https://pm.ljsea.top/tool/third_party_callback") + params.Add("response_type", "code") //直接返回token + params.Add("state", stateBase64Str) + respUrl = fmt.Sprintf("%s?%s", proto.FacebookAuthorizeBaseUrl, params.Encode()) + default: + log.Println("platform not support:", platform) } resp.Message = "success" resp.Code = proto.SuccessCode diff --git a/proto/status.go b/proto/status.go index 1ce65ad..9a5eb89 100644 --- a/proto/status.go +++ b/proto/status.go @@ -189,8 +189,9 @@ const ( // 第三方登录设计url const ( - GitHuAuthorizeBaseUrl = "https://github.com/login/oauth/authorize" - QQAuthorizeBaseUrl = "https://graph.qq.com/oauth2.0/authorize" - GiteeAuthorizeBaseUrl = "https://gitee.com/oauth/authorize" - GoogleAuthorizeBaseUrl = "https://accounts.google.com/o/oauth2/v2/auth" + GitHuAuthorizeBaseUrl = "https://github.com/login/oauth/authorize" + QQAuthorizeBaseUrl = "https://graph.qq.com/oauth2.0/authorize" + GiteeAuthorizeBaseUrl = "https://gitee.com/oauth/authorize" + GoogleAuthorizeBaseUrl = "https://accounts.google.com/o/oauth2/v2/auth" + FacebookAuthorizeBaseUrl = "https://www.facebook.com/v22.0/dialog/oauth" ) diff --git a/proto/tool.go b/proto/tool.go index 4788962..c76e73e 100644 --- a/proto/tool.go +++ b/proto/tool.go @@ -203,3 +203,34 @@ type GoogleOAuthCallback struct { Scope string `json:"scope"` // scope State string `json:"state"` // state } + +/**************************facebook****************************/ +type FacebookOAuthResponse struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + ExpiresIn int `json:"expires_in"` +} + +type FaceBookOAuthRequest struct { + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + Code string `json:"code"` + RedirectURI string `json:"redirect_uri"` +} + +type FaceBookUserInfoResp struct { + ID string `json:"id"` + Name string `json:"name"` + Picture FaceBookUserInfoPicture `json:"picture"` +} + +type FaceBookUserInfoPicture struct { + Data FaceBookUserInfoPictureData `json:"data"` +} + +type FaceBookUserInfoPictureData struct { + Height int `json:"height"` + Width int `json:"width"` + IsSilhouette bool `json:"is_silhouette"` + Url string `json:"url"` +} diff --git a/service/toolService.go b/service/toolService.go index 0531f7d..8f0e709 100644 --- a/service/toolService.go +++ b/service/toolService.go @@ -485,6 +485,8 @@ func DoThirdPartyCallBack(state *proto.ThirdPartyLoginState, code string) { log.Println("DoThirdPartyCallBack gogs error:", state.Platform) case "google": DoGoogleCallBack(state, code) + case "facebook": + DoFaceBookCallBack(state, code) default: log.Println("DoThirdPartyCallBack platform error:", state.Platform) } @@ -516,6 +518,32 @@ func DoGoogleCallBack(state *proto.ThirdPartyLoginState, code string) { worker.SetRedisWithExpire(state.UUID, string(thirdPartyLoginStatusStr), time.Minute*10) } +func DoFaceBookCallBack(state *proto.ThirdPartyLoginState, code string) { + //根据code获取Access Token + tokenResp, err := worker.GetFacebookAccessTokenByCode(code, "https://pm.ljsea.top/tool/third_party_callback", worker.GoogleClientID, worker.GoogleClientSecret) + + if tokenResp.AccessToken == "" { + log.Println("get google access token is empty") + return + } + log.Println("get google access token:", tokenResp) + //获取用户信息 + userInfo, err := worker.GetFaceBookUserInfo(tokenResp.AccessToken) + if err != nil { + log.Println("get google user info error:", err) + return + } + log.Println("get github user info:", userInfo) + var thirdPartyLoginStatus proto.ThirdPartyLoginStatus + thirdPartyLoginStatus.Type = state.Platform + thirdPartyUserInfo := proto.ThirdPartyUserInfo{UserID: userInfo.ID, Name: userInfo.Name, Avatar: "", Email: ""} + HandleThirdPartyLoginStatusV2(state, &thirdPartyLoginStatus, &thirdPartyUserInfo) + //更新redis中的第三方登录状态 + thirdPartyLoginStatusStr, _ := json.Marshal(thirdPartyLoginStatus) + log.Println("do handle google 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 diff --git a/worker/thirdParty.go b/worker/thirdParty.go index 6840216..01e9b90 100644 --- a/worker/thirdParty.go +++ b/worker/thirdParty.go @@ -291,3 +291,84 @@ func GetGoogleUserInfo(accessToken string) (proto.GoogleUserInfoResp, error) { } return resp, nil } + +// facebook +const ( + FacebookClientID = "1171721801397908" + FacebookClientSecret = "e5eadef4d764e4458fc68bd1e4792dbf" +) + +func GetFacebookAccessTokenByCode(code string, redirectURI string, clientID string, clientSecret string) (proto.FacebookOAuthResponse, error) { + var resp proto.FacebookOAuthResponse + + url := "https://graph.facebook.com/v22.0/oauth/access_token" + req := proto.FaceBookOAuthRequest{ + ClientID: clientID, + ClientSecret: clientSecret, + Code: code, + RedirectURI: redirectURI, + } + var onlineReq proto.OnlineServerReq + onlineReq.Type = "get" + onlineReq.Url = url + superTokens := GetRedisSetMembers("super_permission_tokens") + onlineReq.Data = req + onlineReqBytes, _ := json.Marshal(onlineReq) + headers := map[string]string{ + "token": superTokens[0], + "super_id": "1", + } + + log.Println("GetFacebookAccessTokenByCode onlineReqBytes:", string(onlineReqBytes)) + err, respBytes := DoPostRequestJSON("https://vis.ljsea.top/tool/online_server_request?super_id=1", onlineReqBytes, headers) + log.Println("GetFacebookAccessTokenByCode respBytes:", string(respBytes)) + var onlineResp proto.OutlineServerReqResp + err = json.Unmarshal(respBytes, &onlineResp) + if err != nil { + return resp, err + } + err = json.Unmarshal([]byte(onlineResp.Data.Response.Response), &resp) + if err != nil { + return resp, err + } + return resp, nil + +} + +func GetFaceBookUserInfo(accessToken string) (proto.FaceBookUserInfoResp, error) { + var resp proto.FaceBookUserInfoResp + url := "https://graph.facebook.com/v22.0/me?fields=id,name" + var onlineReq proto.OnlineServerReq + onlineReq.Type = "get" + onlineReq.Url = url + onlineReqHeader := make([]proto.OutlineServerReqData, 0) + onlineReqHeader = append(onlineReqHeader, proto.OutlineServerReqData{ + Key: "Authorization", + Value: "Bearer " + accessToken, + }) + onlineReq.Header = onlineReqHeader + superTokens := GetRedisSetMembers("super_permission_tokens") + onlineReqBytes, _ := json.Marshal(onlineReq) + headers := map[string]string{ + "token": superTokens[0], + "super_id": "1", + } + log.Println("GetGoogleUserInfo onlineReqBytes:", string(onlineReqBytes)) + err, respBytes := DoPostRequestJSON("https://vis.ljsea.top/tool/online_server_request?super_id=1", onlineReqBytes, headers) + log.Println("GetGoogleUserInfo respBytes:", string(respBytes)) + var onlineResp proto.OutlineServerReqResp + err = json.Unmarshal(respBytes, &onlineResp) + if err != nil { + return resp, err + } + err = json.Unmarshal([]byte(onlineResp.Data.Response.Response), &resp) + //err, respBytes := DoGetRequest(url, nil) + //if err != nil { + // return resp, err + //} + err = json.Unmarshal(respBytes, &resp) + if err != nil { + return resp, err + } + return resp, nil +}