package logic import ( "fusenapi/utils/auth" "fusenapi/utils/basic" "log" "net/http" "net/url" "time" "context" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" "github.com/474420502/requests" "github.com/zeromicro/go-zero/core/logx" "golang.org/x/net/proxy" "golang.org/x/oauth2" "golang.org/x/oauth2/google" "gorm.io/gorm" ) type UserGoogleLoginLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewUserGoogleLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserGoogleLoginLogic { return &UserGoogleLoginLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:1080", nil, proxy.Direct) if err != nil { log.Fatal(err) } customClient := &http.Client{ Transport: &http.Transport{ Dial: dialer.Dial, }, } ctx := context.WithValue(context.Background(), oauth2.HTTPClient, customClient) var googleOauthConfig = &oauth2.Config{ RedirectURL: "http://localhost:9900/api/user/oauth2/login/google", ClientID: l.svcCtx.Config.OAuth.Google.Appid, ClientSecret: l.svcCtx.Config.OAuth.Google.Secret, Scopes: []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"}, Endpoint: google.Endpoint, } token, err := googleOauthConfig.Exchange(ctx, req.Code) if err != nil { logx.Error(err) resp.SetStatus(basic.CodeApiErr) } ses := requests.NewSession() ses.Config().SetProxy("socks5://127.0.0.1:1080") // 代理 为了测试功能 r, err := ses.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + token.AccessToken).Execute() if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeOAuthGoogleApiErr) } log.Println(r.Json()) googleId := r.Json().Get("id").Int() user, err := l.svcCtx.AllModels.FsUser.FindUserByGoogleId(context.TODO(), googleId) log.Println(user) if err != nil { if err != gorm.ErrRecordNotFound { logx.Error(err) return resp.SetStatus(basic.CodeDbSqlErr) } // 如果密码匹配,则生成 JWT Token。 nowSec := time.Now().Unix() jwtToken, err := auth.GenerateJwtToken(&l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, 0, 0) // 如果生成 JWT Token 失败,则抛出错误并返回未认证的状态码。 if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeServiceErr) } return resp.SetRewriteHandler(func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "http://localhost:9900?token="+url.QueryEscape(jwtToken), http.StatusFound) }) } return resp.SetStatus(basic.CodeOK) }