google第三方登录未完成

This commit is contained in:
junleea 2025-04-28 21:16:35 +08:00
parent f694b0968d
commit e3a5d6e49a
8 changed files with 226 additions and 135 deletions

View File

@ -804,6 +804,13 @@ func GetThirdPartyAuthUrl(c *gin.Context) {
params.Add("redirect_uri", "https://pm.ljsea.top/tool/gitee_callback")
baseUri := proto.GiteeAuthorizeBaseUrl
respUrl = fmt.Sprintf("%s?%s", baseUri, params.Encode())
case "google":
params := url.Values{}
params.Add("client_id", worker.GoogleClientID)
params.Add("response_type", "code")
params.Add("redirect_uri", "https://pm.ljsea.top/tool/third_party_callback")
params.Add("scope", "https://www.googleapis.com/auth/drive.metadata.readonly+https://www.googleapis.com/auth/calendar.readonly")
params.Add("state", stateBase64Str)
}
resp.Message = "success"
resp.Code = proto.SuccessCode
@ -834,8 +841,9 @@ func handleThirdPartyCallback(c *gin.Context) {
log.Println("handle github callback state:", decodedStr, "\tcode:", code)
if err != nil {
log.Println("json unmarshal error:", err)
} else {
service.DoThirdPartyCallBack(&state, code)
}
service.DoThirdPartyCallBack(&state, code)
}
resp.Code = 0
resp.Message = "success"

View File

@ -9,7 +9,7 @@ import (
var Config ConfigStruct
var SigningKey = []byte{}
var Url_map = map[string]bool{"/login": true, "/register": true, "/uuid": true, "/gqr": true, "/cid/callback": true, "/tool/monitor": true, "/user/sync": true, "/tool/file/": true, "/user/reset": true, "/tool/qq_auth": true, "/tool/qq_callback": true, "/tool/github_auth": true, "/tool/github_callback": true, "/user/oAuth": true, "/user/oAuth_uuid": true, "/tool/loginRedirect": true, "/tool/get_auth_url": true, "/tool/gitee_callback": true, "/tool//third_party_callback": true} // 不需要token验证的url
var Url_map = map[string]bool{"/login": true, "/register": true, "/uuid": true, "/gqr": true, "/cid/callback": true, "/tool/monitor": true, "/user/sync": true, "/tool/file/": true, "/user/reset": true, "/tool/qq_auth": true, "/tool/qq_callback": true, "/tool/github_auth": true, "/tool/github_callback": true, "/user/oAuth": true, "/user/oAuth_uuid": true, "/tool/loginRedirect": true, "/tool/get_auth_url": true, "/tool/gitee_callback": true, "/tool/third_party_callback": true} // 不需要token验证的url
var Per_menu_map = map[string]int{"/video/": 1, "/device/": 2, "/cid/": 3}
var File_Type = map[string]int{"im": 1, "avatar": 2, "file": 3, "config": 4} // 文件类型
const (

View File

@ -189,7 +189,8 @@ const (
// 第三方登录设计url
const (
GitHuAuthorizeBaseUrl = "https://github.com/login/oauth/authorize"
QQAuthorizeBaseUrl = "https://graph.qq.com/oauth2.0/authorize"
GiteeAuthorizeBaseUrl = "https://gitee.com/oauth/authorize"
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"
)

View File

@ -101,6 +101,15 @@ type GiteeOAuthTokenResponse struct {
ErrorDescription string `json:"error_description"`
}
type GoogleOAuthResponse struct {
}
type GoogleOAuthRequest struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
Code string `json:"code"`
}
type OAuthGetTokenRequest struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`

View File

@ -412,7 +412,40 @@ func DoThirdPartyCallBack(state *proto.ThirdPartyLoginState, code string) {
// TODO
case "gogs":
// TODO
log.Println("DoThirdPartyCallBack gogs error:", state.Platform)
case "google":
DoGoogleCallBack(state, code)
default:
log.Println("DoThirdPartyCallBack platform error:", state.Platform)
}
}
func DoGoogleCallBack(state *proto.ThirdPartyLoginState, code string) {
//获取Access Token
resp, err := worker.GetGiteeAccessTokenByCode(code, "https://pm.ljsea.top/tool/gitee_callback", proto.Config.GITEE_CLIENT_ID, proto.Config.GITEE_CLIENT_SECRET)
if err != nil {
log.Println("get google access token error:", err)
return
}
if resp.AccessToken == "" {
log.Println("get gitee access token is empty")
log.Println("get gitee access token error:", resp)
return
}
log.Println("get gitee access token:", resp.AccessToken)
//获取用户信息
userInfo, err := worker.GetGiteeUserInfo(resp.AccessToken)
if err != nil {
log.Println("get gitee user info error:", err)
return
}
log.Println("get gitee user info:", userInfo)
var thirdPartyLoginStatus proto.ThirdPartyLoginStatus
thirdPartyLoginStatus.Type = state.Platform
HandleThirdPartyLoginStatus(state, &thirdPartyLoginStatus, &userInfo)
//更新redis中的第三方登录状态
thirdPartyLoginStatusStr, _ := json.Marshal(thirdPartyLoginStatus)
log.Println("do handle gitee callback success, third party login status:", string(thirdPartyLoginStatusStr))
worker.SetRedisWithExpire(state.UUID, string(thirdPartyLoginStatusStr), time.Minute*10)
}

View File

@ -1,55 +0,0 @@
package worker
import (
"StuAcaWorksAI/proto"
"encoding/json"
)
func GetGiteeAccessTokenByCode(code string, redirectURI string, clientID string, clientSecret string) (proto.GiteeOAuthTokenResponse, error) {
req := proto.GiteeOAuthRequest{
ClientID: clientID,
ClientSecret: clientSecret,
Code: code,
RedirectURI: redirectURI,
GrantType: "authorization_code",
}
var resp proto.GiteeOAuthTokenResponse
reqBytes, err := json.Marshal(req)
if err != nil {
return resp, err
}
url := "https://gitee.com/oauth/token"
err2, respBytes := DoPostRequestJSON(url, reqBytes, nil)
if err2 != nil {
return resp, err2
}
err = json.Unmarshal(respBytes, &resp)
if err != nil {
return resp, err
}
return resp, nil
}
func GetGiteeUserInfo(accessToken string) (proto.GitHubUserInfo, error) {
url := "https://gitee.com/api/v5/user?access_token=" + accessToken
var resp proto.GitHubUserInfo
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 GetGogsAccessTokenByCode() {
}
func GetGogsUserInfo() {
}

View File

@ -1,75 +0,0 @@
package worker
import (
"StuAcaWorksAI/proto"
"bytes"
"encoding/json"
"errors"
"io"
"net/http"
)
// 获取access token
func ExchangeCodeForAccessToken(clientID, clientSecret, code, redirectURI string) (proto.GitHubOAuthResponse, error) {
request := proto.GitHubOAuthRequest{
ClientID: clientID,
ClientSecret: clientSecret,
Code: code,
RedirectURI: redirectURI,
}
payload, err := json.Marshal(request)
if err != nil {
return proto.GitHubOAuthResponse{}, err
}
req, err := http.NewRequest("POST", "https://github.com/login/oauth/access_token", bytes.NewBuffer(payload))
if err != nil {
return proto.GitHubOAuthResponse{}, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return proto.GitHubOAuthResponse{}, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return proto.GitHubOAuthResponse{}, err
}
var response proto.GitHubOAuthResponse
err = json.Unmarshal(body, &response)
if err != nil {
return proto.GitHubOAuthResponse{}, err
}
return response, nil
}
// 获取用户信息
func GetGitHubUserInfo(accessToken string) (proto.GitHubUserInfo, error) {
url := "https://api.github.com/user"
headers := map[string]string{
"Authorization": "Bearer " + accessToken,
}
err, data := DoGetRequest(url, headers)
var resp proto.GitHubUserInfo
if err != nil {
return resp, err
}
err = json.Unmarshal(data, &resp)
if err != nil {
return resp, err
}
if resp.UserID == 0 {
return resp, errors.New("获取用户信息失败,请检查access_token是否正确")
}
return resp, err
}

170
worker/thirdParty.go Normal file
View File

@ -0,0 +1,170 @@
package worker
import (
"StuAcaWorksAI/proto"
"bytes"
"encoding/json"
"errors"
"io"
"net/http"
)
func GetGiteeAccessTokenByCode(code string, redirectURI string, clientID string, clientSecret string) (proto.GiteeOAuthTokenResponse, error) {
req := proto.GiteeOAuthRequest{
ClientID: clientID,
ClientSecret: clientSecret,
Code: code,
RedirectURI: redirectURI,
GrantType: "authorization_code",
}
var resp proto.GiteeOAuthTokenResponse
reqBytes, err := json.Marshal(req)
if err != nil {
return resp, err
}
url := "https://gitee.com/oauth/token"
err2, respBytes := DoPostRequestJSON(url, reqBytes, nil)
if err2 != nil {
return resp, err2
}
err = json.Unmarshal(respBytes, &resp)
if err != nil {
return resp, err
}
return resp, nil
}
func GetGiteeUserInfo(accessToken string) (proto.GitHubUserInfo, error) {
url := "https://gitee.com/api/v5/user?access_token=" + accessToken
var resp proto.GitHubUserInfo
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 GetGogsAccessTokenByCode() {
}
func GetGogsUserInfo() {
}
// 获取access token
func ExchangeCodeForAccessToken(clientID, clientSecret, code, redirectURI string) (proto.GitHubOAuthResponse, error) {
request := proto.GitHubOAuthRequest{
ClientID: clientID,
ClientSecret: clientSecret,
Code: code,
RedirectURI: redirectURI,
}
payload, err := json.Marshal(request)
if err != nil {
return proto.GitHubOAuthResponse{}, err
}
req, err := http.NewRequest("POST", "https://github.com/login/oauth/access_token", bytes.NewBuffer(payload))
if err != nil {
return proto.GitHubOAuthResponse{}, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return proto.GitHubOAuthResponse{}, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return proto.GitHubOAuthResponse{}, err
}
var response proto.GitHubOAuthResponse
err = json.Unmarshal(body, &response)
if err != nil {
return proto.GitHubOAuthResponse{}, err
}
return response, nil
}
// 获取用户信息
func GetGitHubUserInfo(accessToken string) (proto.GitHubUserInfo, error) {
url := "https://api.github.com/user"
headers := map[string]string{
"Authorization": "Bearer " + accessToken,
}
err, data := DoGetRequest(url, headers)
var resp proto.GitHubUserInfo
if err != nil {
return resp, err
}
err = json.Unmarshal(data, &resp)
if err != nil {
return resp, err
}
if resp.UserID == 0 {
return resp, errors.New("获取用户信息失败,请检查access_token是否正确")
}
return resp, err
}
// 谷歌登录授权
const (
GoogleClientID = "194888366727-2uvqs43mimk46mmilc04pptrjkqfjn97.apps.googleusercontent.com"
GoogleClientSecret = "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"
)
func GetGoogleAccessTokenByCode(code string, redirectURI string, clientID string, clientSecret string) (proto.GoogleOAuthResponse, error) {
var resp proto.GoogleOAuthResponse
url := "https://oauth2.googleapis.com/token"
req := proto.GoogleOAuthRequest{
ClientID: clientID,
ClientSecret: clientSecret,
Code: code,
}
reqBytes, err := json.Marshal(req)
if err != nil {
return resp, err
}
err2, respBytes := DoPostRequestJSON(url, reqBytes, nil)
if err2 != nil {
return resp, err2
}
err = json.Unmarshal(respBytes, &resp)
if err != nil {
return resp, err
}
return resp, nil
}
func GetGoogleUserInfo(accessToken string) (proto.GitHubUserInfo, error) {
var resp proto.GitHubUserInfo
url := "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + accessToken
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
}