markbates/goth

Using the example app (with just Google auth) - "could not find a matching session for this request"

Closed this issue · 9 comments

I'm running an app using Gin and wanted to add Google and possibly a couple other OAuth providers. I ran into an issue where I'm consistently getting the error "could not find a matching session for this request".

After debugging I noticed that "_gothic_session" is always empty. Assuming I was doing something wrong, I found a few implementations and tutorials online, but none of them used gorilla/sessions except for one. After pulling the repo for one not using sessions I got a secure key error. I tried the one using sessions and received the "could not find a matching session for this request" error after going through the google login screens

I decided to pull the example application in this repo - stripped it down to just use google (and run on :8080), and got the same result. So, I added gorilla/sessions and tried again. While I'm able to go through the google auth flow (selecting my user, etc), it errors "could not find a matching session for this request".

Here is the full code I tried to run - with the google Client ID/Secret redacted:

package main

import (
	"fmt"
	"html/template"
	"log"
	"net/http"
	"sort"

	"github.com/gorilla/pat"
	"github.com/gorilla/sessions"
	"github.com/markbates/goth"
	"github.com/markbates/goth/gothic"
	"github.com/markbates/goth/providers/google"
)

func main() {
	store := sessions.NewCookieStore([]byte("My_Secure_key"))
	store.MaxAge(86400 * 30)
	store.Options.Path = "/"
	store.Options.HttpOnly = true
	store.Options.Secure = false
	store.Options.SameSite = http.SameSiteStrictMode

	gothic.Store = store
	goth.UseProviders(
		google.New("CLIENT_ID", "CLIENT_SECRET", "http://127.0.0.1:8080/auth/google/callback"),
	)

	m := map[string]string{
		"google": "Google",
	}
	var keys []string
	for k := range m {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	providerIndex := &ProviderIndex{Providers: keys, ProvidersMap: m}

	p := pat.New()
	p.Get("/auth/{provider}/callback", func(res http.ResponseWriter, req *http.Request) {

		user, err := gothic.CompleteUserAuth(res, req)
		if err != nil {
			fmt.Fprintln(res, err)
			return
		}
		t, _ := template.New("foo").Parse(userTemplate)
		t.Execute(res, user)
	})

	p.Get("/logout/{provider}", func(res http.ResponseWriter, req *http.Request) {
		gothic.Logout(res, req)
		res.Header().Set("Location", "/")
		res.WriteHeader(http.StatusTemporaryRedirect)
	})

	p.Get("/auth/{provider}", func(res http.ResponseWriter, req *http.Request) {
		// try to get the user without re-authenticating
		if gothUser, err := gothic.CompleteUserAuth(res, req); err == nil {
			t, _ := template.New("foo").Parse(userTemplate)
			t.Execute(res, gothUser)
		} else {
			gothic.BeginAuthHandler(res, req)
		}
	})

	p.Get("/", func(res http.ResponseWriter, req *http.Request) {
		t, _ := template.New("foo").Parse(indexTemplate)
		t.Execute(res, providerIndex)
	})

	log.Println("listening on localhost:3000")
	log.Fatal(http.ListenAndServe(":8080", p))
}

type ProviderIndex struct {
	Providers    []string
	ProvidersMap map[string]string
}

var indexTemplate = `{{range $key,$value:=.Providers}}
    <p><a href="/auth/{{$value}}">Log in with {{index $.ProvidersMap $value}}</a></p>
{{end}}`

var userTemplate = `
<p><a href="/logout/{{.Provider}}">logout</a></p>
<p>Name: {{.Name}} [{{.LastName}}, {{.FirstName}}]</p>
<p>Email: {{.Email}}</p>
<p>NickName: {{.NickName}}</p>
<p>Location: {{.Location}}</p>
<p>AvatarURL: {{.AvatarURL}} <img src="{{.AvatarURL}}"></p>
<p>Description: {{.Description}}</p>
<p>UserID: {{.UserID}}</p>
<p>AccessToken: {{.AccessToken}}</p>
<p>ExpiresAt: {{.ExpiresAt}}</p>
<p>RefreshToken: {{.RefreshToken}}</p>
`

For reference, I tried both localhost and 127.0.0.1 along with adding my domain to my hosts file and trying it that way. All resulted in the same. Additionally, I also tried adding a domain to the session options.

Go Version: go version go1.22.4 darwin/amd64
MacOS Sonoma 14.5

Of course, the moment I post this after fighting it for 5 hours I get it to work.

Hey @jvincilione , I'm having the exact same error. What helped you in getting it to work.

I also have the same error @jvincilione, can you explain how to get it to work?

Got it working. The problem with me was that the gorilla/sessions main branch was broken for golang versions <= 1.22. I downgraded to the last release of the package. Then the error was resolved.

I also have the same error @jvincilione, can you explain how to get it to work?

@matwate My issue was that I had store.Options.SameSite = http.SameSiteStrictMode.

My setup is substantially different from when I wrote this, but currently, I have store.Options.SameSite = http.SameSiteLaxMode instead and don't have any issues.

thx @jvincilione ! you saved my day...

I can confirm that store.Options.SameSite = http.SameSiteLaxMode works!

with store.Options.SameSite = http.SameSiteLaxMode I still face the Error #01: could not find a matching session for this request. Anyone still having this error?

@cocoza4 - there are several things that can cause this issue, what have you tried?

I wasted 2 days on this... was failing in chrome while firefox was fine. SameSiteLaxMode works in both now