添加github请求,添加统一获取url接口添加不拦截接口

This commit is contained in:
junleea 2025-04-26 18:59:55 +08:00
parent 5a5c1ae8c3
commit 22474e459f
7 changed files with 241 additions and 16 deletions

View File

@ -97,5 +97,6 @@ func DeleteKnowledgeBase(c *gin.Context) {
resp.Code = proto.ParameterError
resp.Message = "参数错误:" + err.Error()
}
c.JSON(http.StatusOK, resp)
}

View File

@ -6,6 +6,7 @@ import (
"StuAcaWorksAI/service"
"StuAcaWorksAI/service/spark"
"StuAcaWorksAI/worker"
"encoding/base64"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
@ -57,8 +58,9 @@ func SetUpToolGroup(router *gin.Engine) {
toolGroup.POST("/monitor", SetDeviceStatusV2)
toolGroup.POST("/qq_callback", handleQQCallback)
toolGroup.GET("/qq_auth", GetQQAuthUrl)
toolGroup.GET("/github_auth", ToGithubAuthPage)
toolGroup.POST("/github_callback", handleGithubCallback)
toolGroup.GET("/github_auth", GetGithubAuthUrl)
toolGroup.GET("/get_auth_url", GetThirdPartyAuthUrl)
toolGroup.GET("/github_callback", handleGithubCallback)
toolGroup.POST("/loginRedirect", LoginRedirect)
//发送邮件
toolGroup.POST("/send_mail", SendMailTool)
@ -641,10 +643,29 @@ func GetSparkCreatePPTStatus(c *gin.Context) {
}
func handleGithubCallback(c *gin.Context) {
var resp proto.GenerateResp
code := c.Query("code") //code
stateBase64Str := c.Query("state") //state
//解析base64
decodedBytes, err := base64.StdEncoding.DecodeString(stateBase64Str)
if err != nil {
fmt.Println("Decoding error:", err)
} else {
decodedStr := string(decodedBytes)
//json解析
var state proto.ThirdPartyLoginState
err = json.Unmarshal([]byte(decodedStr), &state)
if err != nil {
log.Println("json unmarshal error:", err)
}
service.DoGithubCallBack(&state, code)
}
resp.Code = 0
resp.Message = "success"
c.JSON(http.StatusOK, resp)
}
func ToGithubAuthPage(c *gin.Context) {
func GetGithubAuthUrl(c *gin.Context) {
uuid := c.Query("uuid")
hType := c.Query("type") //操作类型add,login
var resp proto.GenerateResp
@ -653,21 +674,98 @@ func ToGithubAuthPage(c *gin.Context) {
resp.Message = "uuid or type is empty"
c.JSON(http.StatusOK, resp)
return
} else {
var state proto.ThirdPartyLoginState
state.UUID = uuid
state.Type = hType
state.Platform = "github"
state.Project = "saw"
stateStr, _ := json.Marshal(state)
//base64编码
stateBase64Str := base64.StdEncoding.EncodeToString(stateStr)
params := url.Values{}
params.Add("client_id", proto.Config.GITHUB_CLIENT_ID)
params.Add("login", uuid)
params.Add("state", stateBase64Str)
baseUri := "https://github.com/login/oauth/authorize"
redirectUrl := fmt.Sprintf("%s?%s", baseUri, params.Encode())
//c.Redirect(http.StatusFound, redirectUrl)
resp.Message = "success"
resp.Code = proto.SuccessCode
resp.Data = redirectUrl
c.JSON(http.StatusOK, resp)
}
params := url.Values{}
params.Add("client_id", proto.Config.GITHUB_CLIENT_ID)
params.Add("login", uuid)
params.Add("state", "saw_"+hType+"_"+uuid)
baseUri := "https://github.com/login/oauth/authorize"
redirectUrl := fmt.Sprintf("%s?%s", baseUri, params.Encode())
//c.Redirect(http.StatusFound, redirectUrl)
resp.Message = "success"
resp.Code = proto.SuccessCode
resp.Data = redirectUrl
c.JSON(http.StatusOK, resp)
}
func LoginRedirect(c *gin.Context) {
c.Redirect(http.StatusFound, "https://sv.ljsea.top/") //重定向到登录页面
}
func GetThirdPartyAuthUrl(c *gin.Context) {
platform := c.Query("platform")
uuid := c.Query("uuid")
hType := c.Query("type") //操作类型add,login
var resp proto.GenerateResp
if platform == "" || uuid == "" || hType == "" {
resp.Code = proto.ParameterError
resp.Message = "platform or uuid is empty"
c.JSON(http.StatusOK, resp)
return
}
var state proto.ThirdPartyLoginState
state.UUID = uuid
state.Type = hType
state.Platform = platform
state.Project = "SAW"
if hType == "add" {
//查看是否已经绑定
token := c.Request.Header.Get("token")
if token == "" {
resp.Code = proto.ParameterError
resp.Message = "token is empty"
return
}
userID, err := service.DecodeJWTToken(token)
if err != nil {
resp.Code = proto.ParameterError
resp.Message = err.Error()
return
}
//需要将uuid绑定在该用户上
worker.SetRedisWithExpire("user_add_platform_"+uuid, strconv.Itoa(userID), time.Minute*9)
state.UserID = userID
}
stateStr, _ := json.Marshal(state)
var respUrl string
//base64编码
stateBase64Str := base64.StdEncoding.EncodeToString(stateStr)
switch platform {
case "qq":
params := url.Values{}
params.Add("response_type", "code")
params.Add("client_id", worker.AppId)
params.Add("state", stateBase64Str)
str := fmt.Sprintf("%s", params.Encode())
respUrl = fmt.Sprintf("%s?%s", proto.QQAuthorizeBaseUrl, str)
case "github":
params := url.Values{}
params.Add("client_id", proto.Config.GITHUB_CLIENT_ID)
params.Add("login", uuid)
params.Add("state", stateBase64Str)
baseUri := proto.GitHuAuthorizeBaseUrl
respUrl = fmt.Sprintf("%s?%s", baseUri, params.Encode())
}
resp.Message = "success"
resp.Code = proto.SuccessCode
resp.Data = respUrl
}
type GetThirdPartyAddAuthUrlReq struct {
Platform string `json:"platform" form:"platform"`
Uuid string `json:"uuid" form:"uuid"`
HType string `json:"type" form:"type"` //操作类型add,login
//Platform string `json:"platform" form:"platform"` //操作类型add,login
}

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} // 不需要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} // 不需要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 (
@ -86,6 +86,7 @@ type ConfigStruct struct {
SPARK_PPT_USAGE bool `json:"spark_ppt_usage"` // 是否使用spark ppt功能
KBASE_SERVER []KBaseServer `json:"kbase_server"` // 知识库服务器列表
GITHUB_CLIENT_ID string `json:"github_client_id"` // github client id
GITHUB_CLIENT_SECRET string `json:"github_client_secret"` // github client secret
}
type KBaseServer struct {

View File

@ -183,3 +183,9 @@ const (
FileTypeText = "text_file"
FileTypeImage = "image_file"
)
// 第三方登录设计url
const (
GitHuAuthorizeBaseUrl = "https://github.com/login/oauth/authorize"
QQAuthorizeBaseUrl = "https://graph.qq.com/oauth2.0/authorize"
)

View File

@ -68,3 +68,27 @@ type UserLoginInfo struct {
Email string `json:"email"` // 用户邮箱
Token string `json:"token"` // 用户token
}
// 第三方登录state
type ThirdPartyLoginState struct {
UUID string `json:"uuid"` // uuid
Type string `json:"type"` // 操作类型add,login
Project string `json:"project"` // 项目名称,saw
//第三方平台
Platform string `json:"platform"` // 平台名称,qq,github
UserID int `json:"user_id"` // 用户ID,当为add时需要
}
// github
type GitHubOAuthResponse struct {
AccessToken string `json:"access_token"`
Scope string `json:"scope"`
TokenType string `json:"token_type"`
}
type GitHubOAuthRequest struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
Code string `json:"code"`
RedirectURI string `json:"redirect_uri"`
}

View File

@ -6,6 +6,7 @@ import (
"StuAcaWorksAI/worker"
"encoding/json"
"fmt"
"github.com/golang-jwt/jwt"
"log"
"regexp"
"time"
@ -201,3 +202,34 @@ func SetDashboardInfoToRedis() {
}
}
func DoGithubCallBack(state *proto.ThirdPartyLoginState, code string) {
//获取Access Token
}
// 解析jwt内容
func DecodeJWTToken(tokenStr string) (int, error) {
//解析jwt
// 使用加密secret 解析 JWT 令牌
token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
return proto.SigningKey, nil
})
if err != nil {
return 0, err
}
// 验证令牌
if !token.Valid {
return 0, fmt.Errorf("invalid token")
}
// 获取用户ID
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
return 0, fmt.Errorf("invalid token claims")
}
userID, ok := claims["id"].(float64)
if !ok {
return 0, fmt.Errorf("invalid token claims")
}
return int(userID), nil
}

63
worker/github.go Normal file
View File

@ -0,0 +1,63 @@
package worker
import (
"StuAcaWorksAI/proto"
"bytes"
"encoding/json"
"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) {
url := "https://api.github.com/user"
headers := map[string]string{
"Authorization": "Bearer " + accessToken,
}
err, data := DoGetRequest(url, headers)
}