-
Notifications
You must be signed in to change notification settings - Fork 629
Open
Description
My oauth is not working for production, I deployed the server and client as web service on render.com using docker container.
Here is the server url : server(go)
and client url: nextjs
The error I am getting from the server is: "Error completing OAuth authentication: could not find a matching session for this request."
router.go
package router
import (
"net/http"
"time"
"github.com/cprakhar/datawhiz/config"
"github.com/cprakhar/datawhiz/internal/handlers"
"github.com/cprakhar/datawhiz/internal/middleware"
"github.com/gin-contrib/cors"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
"github.com/markbates/goth/gothic"
)
// NewRouter initializes the Gin router with the necessary routes and middleware.
func NewRouter(cfg *config.Config) *gin.Engine {
router := gin.Default()
var sameSite http.SameSite
switch cfg.Env.SameSite {
case "lax":
sameSite = http.SameSiteLaxMode
case "strict":
sameSite = http.SameSiteStrictMode
case "none":
sameSite = http.SameSiteNoneMode
default:
sameSite = http.SameSiteLaxMode // Default to Lax if not specified
}
store := cookie.NewStore([]byte(cfg.Env.SessionSecret))
store.Options(sessions.Options{
Path: "/",
MaxAge: int(cfg.Env.SessionMaxAge),
HttpOnly: true,
Secure: cfg.Env.SessionSecure,
SameSite: sameSite,
})
gothic.Store = store
cors := cors.New(cors.Config{
AllowOrigins: []string{cfg.Env.FrontendBaseURL},
AllowMethods: []string{"GET", "POST", "PUT", "PATCH","DELETE", "OPTIONS"},
AllowHeaders: []string{"Origin", "Content-Type", "Accept", "Authorization"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
})
router.Use(sessions.Sessions(gothic.SessionName, store))
router.Use(cors)
h := &handlers.Handler{Cfg: cfg}
h.InitProviders()
api := router.Group("/api/v1")
api.GET("/health", h.HandleHealthCheck)
api.POST("/auth/register", h.HandleRegister)
api.GET("/auth/oauth/signin", h.HandleOAuthSignIn)
api.GET("/auth/oauth/callback", h.HandleOAuthCallback)
api.POST("/auth/login", h.HandleLogin)
api.POST("/auth/logout", middleware.RequireAuth(), h.HandleLogout)
api.GET("/auth/me", middleware.RequireAuth(), h.HandleMe)
api.GET("/connections", middleware.RequireAuth(), h.HandleGetConnections)
api.GET("/connections/:id", middleware.RequireAuth(), h.HandleGetConnection)
api.POST("/connections/ping", middleware.RequireAuth(), h.HandlePingConnection)
api.POST("/connections", middleware.RequireAuth(), h.HandleCreateConnection)
api.POST("/connections/:id/activate", middleware.RequireAuth(), h.HandleActivateConnection)
api.DELETE("/connections/:id/deactivate", middleware.RequireAuth(), h.HandleDeactivateConnection)
api.DELETE("/connections/:id", middleware.RequireAuth(), h.HandleDeleteConnection)
api.GET("/tables/:id", middleware.RequireAuth(), h.HandleGetTables)
api.GET("/tables/:id/:table_name/schema", middleware.RequireAuth(), h.HandleGetTableSchema)
api.GET("/tables/:id/:table_name/records", middleware.RequireAuth(), h.HandleGetTableRecords)
api.POST("/query/:id/generate", middleware.RequireAuth(), h.HandleGenerateQuery)
api.POST("/query/:id/execute", middleware.RequireAuth(), h.HandleExecuteQuery)
api.GET("/query/history/:id", middleware.RequireAuth(), h.HandleGetQueryHistory)
api.DELETE("/query/history/:id", middleware.RequireAuth(), h.HandleDeleteQueryHistory)
return router
}oauth.go
package handlers
import (
"context"
"log"
"net/http"
"github.com/cprakhar/datawhiz/internal/database/schema"
"github.com/cprakhar/datawhiz/internal/database/users"
"github.com/cprakhar/datawhiz/utils/response"
"github.com/cprakhar/datawhiz/utils/secure"
"github.com/gin-gonic/gin"
"github.com/markbates/goth"
"github.com/markbates/goth/gothic"
"github.com/markbates/goth/providers/github"
"github.com/markbates/goth/providers/google"
)
// InitProviders initializes the OAuth providers with the necessary credentials.
func (h *Handler) InitProviders() {
goth.UseProviders(
google.New(
h.Cfg.Env.GoogleClientID,
h.Cfg.Env.GoogleClientSecret,
h.Cfg.Env.BackendBaseURL + "/api/v1/auth/oauth/callback?provider=google",
"email", "profile",
),
github.New(
h.Cfg.Env.GitHubClientID,
h.Cfg.Env.GitHubClientSecret,
h.Cfg.Env.BackendBaseURL + "/api/v1/auth/oauth/callback?provider=github",
"read:user",
),
)
}
// HandleOAuthSignIn initiates the OAuth sign-in process by redirecting to the provider's authentication page.
func (h *Handler) HandleOAuthSignIn (ctx *gin.Context) {
provider := ctx.Query("provider")
log.Println(ctx.Request.URL)
type providerKeyType string
const providerKey providerKeyType = "oauth_provider"
req := ctx.Request.WithContext(context.WithValue(ctx, providerKey, provider))
session, err := gothic.Store.Get(ctx.Request, gothic.SessionName)
if err != nil {
log.Println("Error getting session:", err)
response.InternalError(ctx, err)
return
}
session.Values["oauth_provider"] = provider
session.Save(ctx.Request, ctx.Writer)
gothic.BeginAuthHandler(ctx.Writer, req)
}
// HandleOAuthCallback handles the OAuth callback after the user has authenticated with the provider.
func (h *Handler) HandleOAuthCallback(ctx *gin.Context) {
provider := ctx.Query("provider")
redirectURL := h.Cfg.Env.FrontendBaseURL + "/auth/oauth/callback?provider=" + provider
req := gothic.GetContextWithProvider(ctx.Request, provider)
user, err := gothic.CompleteUserAuth(ctx.Writer, req)
if err != nil {
log.Println("Error completing OAuth authentication:", err)
ctx.Redirect(http.StatusTemporaryRedirect, redirectURL+"&status=error")
return
}
exists, err := users.CheckUserExists(h.Cfg.DBClient, user.Email)
if err != nil {
log.Println("Error checking if user exists:", err)
ctx.Redirect(http.StatusTemporaryRedirect, redirectURL+"&status=error")
return
}
if !exists {
newUser := &schema.User{
Name: user.Name,
Email: user.Email,
AvatarURL: user.AvatarURL,
OAuthProvider: provider,
OAuthID: user.UserID,
}
createdUser, err := users.InsertOneUser(h.Cfg.DBClient, newUser)
if err != nil {
log.Println("Error creating new user:", err)
ctx.Redirect(http.StatusTemporaryRedirect, redirectURL+"&status=error")
return
}
err = secure.SetSessionCookie(ctx,
map[string]interface{}{
"user_id": createdUser.ID,
"email": createdUser.Email,
},
)
if err != nil {
log.Println("Error setting session cookie:", err)
ctx.Redirect(http.StatusTemporaryRedirect, redirectURL+"&status=error")
return
}
ctx.Redirect(http.StatusTemporaryRedirect, redirectURL+"&status=success")
return
}
upsertUser := &schema.User{
Name: user.Name,
Email: user.Email,
AvatarURL: user.AvatarURL,
OAuthProvider: provider,
OAuthID: user.UserID,
}
updatedUser, err := users.UpsertOAuthUser(h.Cfg.DBClient, upsertUser)
if err != nil {
log.Println("Error upserting user:", err)
ctx.Redirect(http.StatusTemporaryRedirect, redirectURL+"&status=error")
return
}
err = secure.SetSessionCookie(ctx,
map[string]interface{}{
"user_id": updatedUser.ID,
"email": updatedUser.Email,
},
)
if err != nil {
log.Println("Error setting session cookie:", err)
ctx.Redirect(http.StatusTemporaryRedirect, redirectURL+"&status=error")
return
}
ctx.Redirect(http.StatusTemporaryRedirect, redirectURL+"&status=success")
}Metadata
Metadata
Assignees
Labels
No labels