Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example on how to use supertokens with go-zero #157

Closed
a0v0 opened this issue Jul 18, 2022 · 2 comments
Closed

Example on how to use supertokens with go-zero #157

a0v0 opened this issue Jul 18, 2022 · 2 comments
Assignees

Comments

@a0v0
Copy link

a0v0 commented Jul 18, 2022

https://github.com/zeromicro/go-zero

I tried to initialize supertokens in go-zero but getting 404. only /sessioninfo endpoint seems to work properly. Here is the code.

package main

import (
	"backbone/service/gateway/api/internal/config"
	"backbone/service/gateway/api/internal/handler"
	"backbone/service/gateway/api/internal/svc"
	"encoding/json"
	"net/http"
	"strings"

	"github.com/supertokens/supertokens-golang/recipe/passwordless"
	"github.com/supertokens/supertokens-golang/recipe/passwordless/plessmodels"

	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/supertokens"

	"flag"
	"fmt"

	"github.com/zeromicro/go-zero/core/conf"
	"github.com/zeromicro/go-zero/rest"
)

var configFile = flag.String("f", "etc/gateway.yaml", "the config file")

func main() {
	flag.Parse()

	var c config.Config
	conf.MustLoad(*configFile, &c)

	server := rest.MustNewServer(c.RestConf)
	defer server.Stop()

	// supertokens
	err := supertokens.Init(supertokens.TypeInput{
		Supertokens: &supertokens.ConnectionInfo{
			//These are the connection details of the app you created on supertokens.com
			ConnectionURI: c.Supertokens.ConnectionURI,
			APIKey:        c.Supertokens.APIKey,
		},
		AppInfo: supertokens.AppInfo{
			AppName:         c.Supertokens.AppName,
			APIDomain:       c.Supertokens.APIDomain,
			WebsiteDomain:   c.Supertokens.WebsiteDomain,
			APIBasePath:     &c.Supertokens.APIBasePath,
			WebsiteBasePath: &c.Supertokens.WebsiteBasePath,
		},
		RecipeList: []supertokens.Recipe{
			passwordless.Init(plessmodels.TypeInput{
				FlowType: "USER_INPUT_CODE_AND_MAGIC_LINK",
				ContactMethodEmailOrPhone: plessmodels.ContactMethodEmailOrPhoneConfig{
					Enabled: true,
				},
			}),
			session.Init(nil), // initializes session features
		},
	})
	if err != nil {
		panic(err.Error())
	}

	server.Use(corsMiddleware)
	server.Use(rest.ToMiddleware(supertokens.Middleware))
	server.AddRoute(rest.Route{
		Method: http.MethodGet,
		Path:   "/sessioninfo",
		Handler: func(rw http.ResponseWriter, r *http.Request) {
			session.VerifySession(nil, sessioninfo).ServeHTTP(rw, r)
		},
	})

	ctx := svc.NewServiceContext(c)
	handler.RegisterHandlers(server, ctx)

	fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
	server.Start()
}

func corsMiddleware(next http.HandlerFunc) http.HandlerFunc {
	return func(response http.ResponseWriter, r *http.Request) {
		var c config.Config
		conf.MustLoad(*configFile, &c)

		response.Header().Set("Access-Control-Allow-Origin", c.Supertokens.WebsiteDomain)
		response.Header().Set("Access-Control-Allow-Credentials", "true")
		if r.Method == "OPTIONS" {
			response.Header().Set("Access-Control-Allow-Headers", strings.Join(append([]string{"Content-Type"}, supertokens.GetAllCORSHeaders()...), ","))
			response.Header().Set("Access-Control-Allow-Methods", "*")
			response.Write([]byte(""))
		} else {
			next.ServeHTTP(response, r)
		}
	}
}

func sessioninfo(w http.ResponseWriter, r *http.Request) {
	sessionContainer := session.GetSessionFromRequestContext(r.Context())

	if sessionContainer == nil {
		w.WriteHeader(500)
		w.Write([]byte("no session found"))
		return
	}
	sessionData, err := sessionContainer.GetSessionData()
	if err != nil {
		err = supertokens.ErrorHandler(err, r, w)
		if err != nil {
			w.WriteHeader(500)
			w.Write([]byte(err.Error()))
		}
		return
	}
	w.WriteHeader(200)
	w.Header().Add("content-type", "application/json")
	bytes, err := json.Marshal(map[string]interface{}{
		"sessionHandle":      sessionContainer.GetHandle(),
		"userId":             sessionContainer.GetUserID(),
		"accessTokenPayload": sessionContainer.GetAccessTokenPayload(),
		"sessionData":        sessionData,
	})
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte("error in converting to json"))
	} else {
		w.Write(bytes)
	}
}
@a0v0 a0v0 changed the title Please add an example to integrate with go-zero framework Example on how to use supertokens with go-zero Jul 18, 2022
@rishabhpoddar
Copy link
Contributor

Thanks for opening this issue @a0v0 . We can have a look at this within a few days.

@rishabhpoddar
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants