Hi, weird ask but don't know how to figure out. I have two roles for my authentication. One can be h...
v
Hi, weird ask but don't know how to figure out. I have two roles for my authentication. One can be handle 100% by supertokens but the other one is a little special. I'm making a MVP product based on Ghost CMS (it's a blogging CMS) and when user signup to my API, this one create an account author on Ghost CMS. My idea was to use Ghost has auth provider when user send credential to login I want to auth over ghost and if credential are good provide a JWT or something to the client. I saw we can create create JWT from backend SDK but how to use JWT on client side with the same way to the 100% supertokens like the other role? Some tips? My first idea is to create a fake session and return it to the client like a real one but the user doesn't exist one supertokens database Don't know if I was clear .. Sorry if not [[UPDATED]]
r
hey @Val
v
hey 🙂
r
you can do that: - enable JWT with session management: https://supertokens.com/docs/session/common-customizations/sessions/with-jwt/enabling-jwts - fetch the JWT on the frontend like this: https://supertokens.com/docs/session/common-customizations/sessions/with-jwt/read-jwt#fetching-the-jwt-on-the-frontend - Don't use the verifySession function and instead use any standard JWT verification lib for your APIs. You can follow JWT verification guide here: https://supertokens.com/docs/session/common-customizations/sessions/with-jwt/jwt-verification
v
Thank for your answer, I don't understand this one fetch the JWT on the frontend That mean the frontend fetch JWT from supertokens but the user doesn't exist on supertokens he exists on Ghost, or that meant my backend SDK create token through supertokens and the frontend can fetch it up?
r
> backend SDK create token through supertokens and the frontend can fetch it up? This. ALso, you can call the createNewSession with supertokens on the backend and pass it a user ID that doesn't exist in superotkens, but in ghost. This would also generate a session with a JWT just like if the user was in supertokens.
v
oh man ! That really great ! 😮 I'm gonna trying this
r
Cool
v
Hey @rp_st that seems to work 🙂 I didn't try frontend side yet. But I've a question how can I decode SAccessToken? To see what I put inside with
CreateNewSession
and
accessTokenPayload
?
r
You should use our library for that. We have functions to get accessTokenPayload
v
can we add dynamically custom payload to access session
Copy code
func main() {
    supertokens.Init(supertokens.TypeInput{
        RecipeList: []supertokens.Recipe{
            session.Init(&sessmodels.TypeInput{
                Override: &sessmodels.OverrideStruct{
                    Functions: func(originalImplementation sessmodels.RecipeInterface) sessmodels.RecipeInterface {
                        // First we copy the original implementation func
                        originalCreateNewSession := *originalImplementation.CreateNewSession

                        // Now we override the CreateNewSession function
                        (*originalImplementation.CreateNewSession) = func(res http.ResponseWriter, userID string, accessTokenPayload, sessionData map[string]interface{}, userContext supertokens.UserContext) (sessmodels.SessionContainer, error) {

                            // This goes in the access token, and is availble to read on the frontend.
                            if accessTokenPayload == nil {
                                accessTokenPayload = map[string]interface{}{}
                            }
                            accessTokenPayload["someKey"] = "someValue"

                            return originalCreateNewSession(res, userID, accessTokenPayload, sessionData, userContext)
                        }

                        return originalImplementation
                    },
                },
            }),
        },
    })
}
Like pass the metadata used when the user was create
?
something like this
Copy code
golang
Functions: func(originalImplementation epmodels.RecipeInterface) epmodels.RecipeInterface {
                        originalSignIn := *originalImplementation.SignIn

                        *originalImplementation.SignIn = func(email, password string, userContext supertokens.UserContext) (epmodels.SignInResponse, error) {
                            // get user metadata and add it to the session
                            /*_, err := session.CreateNewSession(w, userId, map[string]interface{}{
                                "role":     "role",
                                "ghost_id": ghostID,
                            }, nil)*/
                            
                            return originalSignIn(email, password, userContext)
                        }

                        return originalImplementation
                    },
@rp_st I think it's the last question 🥺
the idea it's to have the same process that come from ghost or supertokens account I tried to work with ghost and create my own token it's great and work nice I added metadata to supertokens account with role and ghostID for other role work nicely too Need to create same session for ghost user and supertokens user and I'm all good because for now I only have ghostID and role inside a ghost session and not inside supertokens session I know I'm able to retrieve metadata but should be more nice to have same token
I did
Copy code
golang
Functions: func(originalImplementation sessmodels.RecipeInterface) sessmodels.RecipeInterface {
                        originalCreateNewSession := *originalImplementation.CreateNewSession
                        *originalImplementation.CreateNewSession = func(res http.ResponseWriter, userID string, accessTokenPayload, sessionData map[string]interface{}, userContext supertokens.UserContext) (sessmodels.SessionContainer, error) {
                            metadata, err := usermetadata.GetUserMetadata(userID)
                            if err != nil {
                                return nil, err
                            }

                            if accessTokenPayload == nil {
                                accessTokenPayload = map[string]interface{}{}
                            }

                            if accessTokenPayload["ext_id"] == nil {
                                accessTokenPayload["ext_id"] = metadata["ext_id"]
                            }

                            if accessTokenPayload["role"] == nil {
                                accessTokenPayload["role"] = metadata["role"]
                            }

                            return originalCreateNewSession(res, userID, accessTokenPayload, sessionData, userContext)
                        }

                        return originalImplementation
                    },
If you have a better approche I'm in but it's working 🙂
r
yea! this is good. It's the right way