修复proxy不传递query参数的问题

This commit is contained in:
eson 2023-07-18 13:04:29 +08:00
parent 125de6dde8
commit e4e9339071
9 changed files with 77 additions and 65 deletions

View File

@ -75,10 +75,12 @@ func main() {
fs := http.FileServer(http.Dir(vueBuild)) fs := http.FileServer(http.Dir(vueBuild))
indexHtmlPath := vueBuild + "/index.html" indexHtmlPath := vueBuild + "/index.html"
mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.URL.Path, "/api") { if strings.HasPrefix(r.URL.Path, "/api/") {
// 对/api开头的请求进行反向代理 // 对/api开头的请求进行反向代理
proxy := httputil.NewSingleHostReverseProxy(apiURL) proxy := httputil.NewSingleHostReverseProxy(apiURL)
proxy.ServeHTTP(w, r) proxy.ServeHTTP(w, r)
return
} else { } else {
// 根据请求路径判断是服务静态文件或者是返回index.html // 根据请求路径判断是服务静态文件或者是返回index.html
idx := strings.Index(r.URL.Path[1:], "/") idx := strings.Index(r.URL.Path[1:], "/")
@ -144,7 +146,7 @@ func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Bac
// 创建处理请求的函数 // 创建处理请求的函数
handleRequest := func(w http.ResponseWriter, r *http.Request) { handleRequest := func(w http.ResponseWriter, r *http.Request) {
// 解析目标URL包含了查询参数 // 解析目标URL包含了查询参数
targetURL, err := url.Parse(httpAddress + r.URL.Path) targetURL, err := url.Parse(httpAddress + r.URL.String())
if err != nil { if err != nil {
http.Error(w, "Error parsing target URL", http.StatusInternalServerError) http.Error(w, "Error parsing target URL", http.StatusInternalServerError)
return return

View File

@ -7,9 +7,9 @@ import (
) )
type OAuth struct { type OAuth struct {
Name string `json:"name"` Name string `yaml:"name"`
Appid string `json:"appid"` Appid string `yaml:"appid"`
Secret string `json:"secret"` Secret string `yaml:"secret"`
} }
type Config struct { type Config struct {

View File

@ -68,15 +68,10 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Handler: UserOderDeleteHandler(serverCtx), Handler: UserOderDeleteHandler(serverCtx),
}, },
{ {
Method: http.MethodPost, Method: http.MethodGet,
Path: "/api/user/oauth2/login/google", Path: "/api/user/oauth2/login/google",
Handler: UserGoogleLoginHandler(serverCtx), Handler: UserGoogleLoginHandler(serverCtx),
}, },
{
Method: http.MethodPost,
Path: "/api/user/oauth2/login",
Handler: UserOAuth2LoginHandler(serverCtx),
},
}, },
) )
} }

View File

@ -2,6 +2,7 @@ package handler
import ( import (
"errors" "errors"
"log"
"net/http" "net/http"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
@ -53,6 +54,7 @@ func UserGoogleLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
} }
log.Println(r.URL.String(), r.URL.Query())
var req types.RequestGoogleLogin var req types.RequestGoogleLogin
// 如果端点有请求结构体则使用httpx.Parse方法从HTTP请求体中解析请求数据 // 如果端点有请求结构体则使用httpx.Parse方法从HTTP请求体中解析请求数据
if err := httpx.Parse(r, &req); err != nil { if err := httpx.Parse(r, &req); err != nil {

View File

@ -3,13 +3,17 @@ package logic
import ( import (
"fusenapi/utils/auth" "fusenapi/utils/auth"
"fusenapi/utils/basic" "fusenapi/utils/basic"
"log"
"context" "context"
"fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/svc"
"fusenapi/server/home-user-auth/internal/types" "fusenapi/server/home-user-auth/internal/types"
"github.com/474420502/requests"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
) )
type UserGoogleLoginLogic struct { type UserGoogleLoginLogic struct {
@ -30,5 +34,24 @@ func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, us
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
// userinfo 传入值时, 一定不为null // userinfo 传入值时, 一定不为null
var googleOauthConfig = &oauth2.Config{
RedirectURL: "http://localhost:9900/api/user/oauth2/login/google",
ClientID: l.svcCtx.Config.OAuth[0].Appid,
ClientSecret: l.svcCtx.Config.OAuth[0].Secret,
Scopes: []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"},
Endpoint: google.Endpoint,
}
token, err := googleOauthConfig.Exchange(context.Background(), req.Code)
if err != nil {
resp.SetStatus(basic.CodeApiErr)
}
r, err := requests.Get("https://www.googleapis.com/oauth2/v2/userinfo" + token.AccessToken).Execute()
if err != nil {
panic(err)
}
log.Println(r.Json())
return resp.SetStatus(basic.CodeOK) return resp.SetStatus(basic.CodeOK)
} }

View File

@ -3,17 +3,13 @@ package logic
import ( import (
"fusenapi/utils/auth" "fusenapi/utils/auth"
"fusenapi/utils/basic" "fusenapi/utils/basic"
"log"
"context" "context"
"fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/svc"
"fusenapi/server/home-user-auth/internal/types" "fusenapi/server/home-user-auth/internal/types"
"github.com/474420502/requests"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
) )
type UserOAuth2LoginLogic struct { type UserOAuth2LoginLogic struct {
@ -34,31 +30,6 @@ func NewUserOAuth2LoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *U
func (l *UserOAuth2LoginLogic) UserOAuth2Login(req *types.RequestOAuth, userinfo *auth.UserInfo) (resp *basic.Response) { func (l *UserOAuth2LoginLogic) UserOAuth2Login(req *types.RequestOAuth, userinfo *auth.UserInfo) (resp *basic.Response) {
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
// userinfo 传入值时, 一定不为null // userinfo 传入值时, 一定不为null
switch req.Platform {
case "google":
var googleOauthConfig = &oauth2.Config{
RedirectURL: "https://fusenh5.kayue.cn/api/user/oauth2/login/google",
ClientID: l.svcCtx.Config.OAuth[0].Appid,
ClientSecret: l.svcCtx.Config.OAuth[0].Secret,
Scopes: []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"},
Endpoint: google.Endpoint,
}
token, err := googleOauthConfig.Exchange(context.Background(), req.Code)
if err != nil {
resp.SetStatus(basic.CodeApiErr)
}
resp, err := requests.Get("https://www.googleapis.com/oauth2/v2/userinfo" + token.AccessToken).Execute()
if err != nil {
panic(err)
}
log.Println(resp.Json())
case "facebook":
default:
}
return resp.SetStatus(basic.CodeOK) return resp.SetStatus(basic.CodeOK)
} }

View File

@ -6,16 +6,10 @@ import (
) )
type RequestGoogleLogin struct { type RequestGoogleLogin struct {
ID string `json:"id,,optional"` Code string `form:"code"`
Email string `json:"email,,optional"` Scope string `form:"scope"`
VerifiedEmail bool `json:"verified_email,,optional"` AuthUser string `form:"authuser"`
Name string `json:"name,,optional"` Prompt string `form:"prompt"`
GivenName string `json:"given_name,,optional"`
FamilyName string `json:"family_name,,optional"`
Link string `json:"link,,optional"`
Picture string `json:"picture,,optional"`
Gender string `json:"gender,,optional"`
Locale string `json:"locale,,optional"`
} }
type RequestOAuth struct { type RequestOAuth struct {

View File

@ -32,33 +32,53 @@ func NewUploadFileBackendLogic(ctx context.Context, svcCtx *svc.ServiceContext)
} }
} }
// UploadFileBackend 这个函数接收一个文件上传请求和用户信息,处理文件上传,并返回响应
func (l *UploadFileBackendLogic) UploadFileBackend(req *types.RequestUploadFileBackend, userinfo *auth.UserInfo) (resp *basic.Response) { func (l *UploadFileBackendLogic) UploadFileBackend(req *types.RequestUploadFileBackend, userinfo *auth.UserInfo) (resp *basic.Response) {
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
// userinfo 传入值时, 一定不为null // userinfo 传入值时, 一定不为null
// 检查用户是否是旁观者,旁观者没有文件上传权限
if userinfo.IsOnlooker() { if userinfo.IsOnlooker() {
// 如果是,返回未授权的错误码
return resp.SetStatus(basic.CodeUnAuth) return resp.SetStatus(basic.CodeUnAuth)
} }
// 定义用户ID和S3键名格式
var uid int64 var uid int64
var keytype format.TypeFormatS3KeyName var keytype format.TypeFormatS3KeyName
// 检查用户是否是游客
if userinfo.IsGuest() { if userinfo.IsGuest() {
// 如果是使用游客ID和游客键名格式
uid = userinfo.GuestId uid = userinfo.GuestId
keytype = format.TypeS3KeyGuest keytype = format.TypeS3KeyGuest
} else { } else {
// 否则使用用户ID和用户键名格式
uid = userinfo.UserId uid = userinfo.UserId
keytype = format.TypeS3KeyUser keytype = format.TypeS3KeyUser
} }
// 设置AWS会话的区域
l.svcCtx.AwsSession.Config.Region = aws.String("us-west-1") l.svcCtx.AwsSession.Config.Region = aws.String("us-west-1")
// 创建新的S3服务实例
svc := s3.New(l.svcCtx.AwsSession) svc := s3.New(l.svcCtx.AwsSession)
// 检查类别是否合法
if !check.CheckCategory(req.Category) { if !check.CheckCategory(req.Category) {
// 如果不合法,返回类别错误的错误码
return resp.SetStatus(basic.CodeS3CategoryErr) return resp.SetStatus(basic.CodeS3CategoryErr)
} }
// 定义S3请求和当前时间
var s3req *request.Request var s3req *request.Request
now := time.Now() now := time.Now()
// 格式化类别
category := format.TypeCategory(req.Category) category := format.TypeCategory(req.Category)
// 格式化S3对象键名
ObjectKey := aws.String(format.FormatS3KeyName( ObjectKey := aws.String(format.FormatS3KeyName(
keytype, keytype,
uid, uid,
@ -68,7 +88,10 @@ func (l *UploadFileBackendLogic) UploadFileBackend(req *types.RequestUploadFileB
req.File.Filename, req.File.Filename,
)) ))
// 定义存储桶名称
var bucketName *string var bucketName *string
// 根据类别选择存储桶
switch category { switch category {
case format.TCategoryRenderMegre: case format.TCategoryRenderMegre:
bucketName = basic.TempfileBucketName bucketName = basic.TempfileBucketName
@ -76,21 +99,32 @@ func (l *UploadFileBackendLogic) UploadFileBackend(req *types.RequestUploadFileB
bucketName = basic.StorageBucketName bucketName = basic.StorageBucketName
} }
// 创建S3对象存储请求
s3req, _ = svc.PutObjectRequest( s3req, _ = svc.PutObjectRequest(
&s3.PutObjectInput{ &s3.PutObjectInput{
Bucket: bucketName, Bucket: bucketName,
Key: ObjectKey, Key: ObjectKey,
}, },
) )
// 设置请求体为文件数据
s3req.SetBufferBody(req.File.Data) s3req.SetBufferBody(req.File.Data)
// 发送请求
err := s3req.Send() err := s3req.Send()
// 检查是否有错误
if err != nil { if err != nil {
// 如果有,打印错误并返回错误码
logx.Error(err) logx.Error(err)
return resp.SetStatus(basic.CodeS3PutObjectRequestErr) return resp.SetStatus(basic.CodeS3PutObjectRequestErr)
} }
// 打印请求URL
logx.Info(s3req.HTTPRequest.URL.String()) logx.Info(s3req.HTTPRequest.URL.String())
// 返回成功的响应和上传URL
return resp.SetStatus(basic.CodeOK, map[string]interface{}{ return resp.SetStatus(basic.CodeOK, map[string]interface{}{
"upload_url": s3req.HTTPRequest.URL.String(), "upload_url": s3req.HTTPRequest.URL.String(),
}) })
} }

View File

@ -51,24 +51,15 @@ service home-user-auth {
post /api/user/order-delete(RequestOrderId) returns (response); post /api/user/order-delete(RequestOrderId) returns (response);
@handler UserGoogleLoginHandler @handler UserGoogleLoginHandler
post /api/user/oauth2/login/google(RequestGoogleLogin) returns (response); get /api/user/oauth2/login/google(RequestGoogleLogin) returns (response);
@handler UserOAuth2LoginHandler
post /api/user/oauth2/login(RequestOAuth) returns (response);
} }
type RequestGoogleLogin { type RequestGoogleLogin {
ID string `json:"id,,optional"` Code string `form:"code"`
Email string `json:"email,,optional"` Scope string `form:"scope"`
VerifiedEmail bool `json:"verified_email,,optional"` AuthUser string `form:"authuser"`
Name string `json:"name,,optional"` Prompt string `form:"prompt"`
GivenName string `json:"given_name,,optional"`
FamilyName string `json:"family_name,,optional"`
Link string `json:"link,,optional"`
Picture string `json:"picture,,optional"`
Gender string `json:"gender,,optional"`
Locale string `json:"locale,,optional"`
} }
type RequestOAuth { type RequestOAuth {