Get User Info
There are several ways to fetch information about a user:
- Using their user ID, you can get their email ID, time joined, and metadata that is saved in the user metadata recipe.
- If the user logged in via a third party providers, you can get their profile info in the post sign up override along with the provider's access token. You can save this information in the user metadata recipe for later retrieval.
- Lastly, you can get the user's session information and access token payload from their session handle (offline mode), or from the currently logged in session object (online mode).
#
Fetching information using the user's email- NodeJS
- GoLang
- Python
- Other Frameworks
Important
Use the listUsersByAccountInfo
function to retrieve a user's data, specifying the account type and providing the user's email as criteria.
import supertokens from "supertokens-node";
async function getUserInfo() {
let usersInfo = await supertokens.listUsersByAccountInfo("public", {
email: "[email protected]"
});
/**
*
* userInfo contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
}
You can get a user's information on the backend using the GetUsersByEmail
function:
import (
"fmt"
"github.com/supertokens/supertokens-golang/recipe/emailpassword"
"github.com/supertokens/supertokens-golang/recipe/thirdparty"
)
func main() {
// Note that usersInfo has type User[]
// You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
thirdPartyUserInfo, err := thirdparty.GetUsersByEmail("public", "[email protected]")
if err != nil {
// TODO: Handle error
return
}
emailPasswordUserInfo, err := emailpassword.GetUserByEmail("public", "[email protected]")
if err != nil {
// TODO: Handle error
return
}
if emailPasswordUserInfo != nil {
fmt.Println(emailPasswordUserInfo)
}
if len(thirdPartyUserInfo) > 0 {
fmt.Println(thirdPartyUserInfo)
}
//...
}
- Asyncio
- Syncio
You can get a user's information on the backend using the list_users_by_account_info
function:
from supertokens_python.asyncio import list_users_by_account_info
from supertokens_python.types import AccountInfo
async def some_func():
# Note that users_info has type List[User]
user_info = await list_users_by_account_info("public", AccountInfo(email="[email protected]"))
print(user_info)
#
# user_info contains the following info:
# - emails
# - id
# - timeJoined
# - tenantIds
# - phone numbers
# - third party login info
# - all the login methods associated with this user.
# - information about if the user's email is verified or not.
#
You can get a user's information on the backend using the list_users_by_account_info
function:
from supertokens_python.syncio import list_users_by_account_info
from supertokens_python.types import AccountInfo
def some_func():
# Note that users_info has type List[User]
user_info = list_users_by_account_info("public", AccountInfo(email="[email protected]"))
print(user_info)
#
# user_info contains the following info:
# - emails
# - id
# - timeJoined
# - tenantIds
# - phone numbers
# - third party login info
# - all the login methods associated with this user.
# - information about if the user's email is verified or not.
#
Multi Tenancy
Notice that the first argument of the above function is "public"
. This is the default tenantId
which means that SuperTokens will return information about the user whose email is "[email protected]"
in the "public"
tenant.
If you are using our multi-tenancy feature, you can pass in a different tenantId
to get information about a user in a different tenant.
#
Fetching information using the user's IDRetrieve the user's ID by calling:
- the
getUser
function for NodeJS - the
GetUserById
function for GoLang - the
get_user_by_id
function for Python
Refer to the code snippets below for example usage:
- NodeJS
- GoLang
- Python
- Other Frameworks
Important
- Express
- Hapi
- Fastify
- Koa
- Loopback
- AWS Lambda / Netlify
- Next.js (Pages Dir)
- Next.js (App Dir)
- NestJS
import express from "express";
import { verifySession } from "supertokens-node/recipe/session/framework/express";
import { SessionRequest } from 'supertokens-node/framework/express';
import supertokens from "supertokens-node";
let app = express();
app.get("/get-user-info", verifySession(), async (req: SessionRequest, res) => {
let userId = req.session!.getUserId();
let userInfo = await supertokens.getUser(userId)
/**
*
* userInfo contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
})
import { verifySession } from "supertokens-node/recipe/session/framework/hapi";
import Hapi from "@hapi/hapi";
import { SessionRequest } from "supertokens-node/framework/hapi";
import supertokens from "supertokens-node";
let server = Hapi.server({ port: 8000 });
server.route({
path: "/get-user-info",
method: "get",
options: {
pre: [
{
method: verifySession()
},
],
},
handler: async (req: SessionRequest, res) => {
let userId = req.session!.getUserId();
let userInfo = await supertokens.getUser(userId)
/**
*
* userInfo contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
}
})
import Fastify from "fastify";
import { verifySession } from "supertokens-node/recipe/session/framework/fastify";
import { SessionRequest } from 'supertokens-node/framework/fastify';
import supertokens from "supertokens-node";
const fastify = Fastify();
fastify.post("/like-comment", {
preHandler: verifySession(),
}, async (req: SessionRequest, res) => {
let userId = req.session!.getUserId();
let userInfo = await supertokens.getUser(userId)
/**
*
* userInfo contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
});
import { verifySession } from "supertokens-node/recipe/session/framework/awsLambda";
import { SessionEvent } from "supertokens-node/framework/awsLambda";
import supertokens from "supertokens-node";
async function getUserInfo(awsEvent: SessionEvent) {
let userId = awsEvent.session!.getUserId();
let userInfo = await supertokens.getUser(userId)
/**
*
* userInfo contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
};
exports.handler = verifySession(getUserInfo);
import KoaRouter from "koa-router";
import { verifySession } from "supertokens-node/recipe/session/framework/koa";
import { SessionContext } from "supertokens-node/framework/koa";
import supertokens from "supertokens-node";
let router = new KoaRouter();
router.get("/get-user-info", verifySession(), async (ctx: SessionContext, next) => {
let userId = ctx.session!.getUserId();
let userInfo = await supertokens.getUser(userId)
/**
*
* userInfo contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
});
import { inject, intercept } from "@loopback/core";
import { RestBindings, MiddlewareContext, get, response } from "@loopback/rest";
import { verifySession } from "supertokens-node/recipe/session/framework/loopback";
import Session from "supertokens-node/recipe/session";
import { SessionContext } from "supertokens-node/framework/loopback";
import supertokens from "supertokens-node";
class GetUserInfo {
constructor(@inject(RestBindings.Http.CONTEXT) private ctx: MiddlewareContext) {}
@get("/get-user-info")
@intercept(verifySession())
@response(200)
async handler() {
let userId = ((this.ctx as any).session as Session.SessionContainer).getUserId();
let userInfo = await supertokens.getUser(userId)
/**
*
* userInfo contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
}
}
import { superTokensNextWrapper } from 'supertokens-node/nextjs'
import { verifySession } from "supertokens-node/recipe/session/framework/express";
import { SessionRequest } from "supertokens-node/framework/express";
import supertokens from "supertokens-node";
export default async function likeComment(req: SessionRequest, res: any) {
await superTokensNextWrapper(
async (next) => {
await verifySession()(req, res, next);
},
req,
res
)
let userId = req.session!.getUserId();
let userInfo = await supertokens.getUser(userId)
/**
*
* userInfo contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
}
import { NextResponse, NextRequest } from "next/server";
import SuperTokens from "supertokens-node";
import { withSession } from "supertokens-node/nextjs";
import { backendConfig } from "@/app/config/backend";
SuperTokens.init(backendConfig());
export function POST(request: NextRequest) {
return withSession(request, async (err, session) => {
if (err) {
return NextResponse.json(err, { status: 500 });
}
const userId = session!.getUserId();
let userInfo = await SuperTokens.getUser(userId)
/**
*
* userInfo contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
return NextResponse.json({});
});
}
import { Controller, Post, UseGuards, Request, Response } from "@nestjs/common";
import { AuthGuard } from './auth/auth.guard';
import { Session } from './auth/session.decorator';
import { SessionRequest } from "supertokens-node/framework/express";
import supertokens from "supertokens-node";
@Controller()
export class ExampleController {
@Post('example')
@UseGuards(new AuthGuard()) // For more information about this guard please read our NestJS guide.
async postExample(@Request() req: SessionRequest, @Session() session: Session, @Response({passthrough: true}) res: Response): Promise<boolean> {
let userId = session.getUserId();
let userInfo = await supertokens.getUser(userId)
/**
*
* userInfo contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
return true;
}
}
- Chi
- net/http
- Gin
- Mux
import (
"fmt"
"net/http"
"github.com/supertokens/supertokens-golang/recipe/emailpassword"
"github.com/supertokens/supertokens-golang/recipe/session"
"github.com/supertokens/supertokens-golang/recipe/thirdparty"
)
func main() {
_ = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
session.VerifySession(nil, getUserInfoAPI).ServeHTTP(rw, r)
})
}
func getUserInfoAPI(w http.ResponseWriter, r *http.Request) {
sessionContainer := session.GetSessionFromRequestContext(r.Context())
userID := sessionContainer.GetUserID()
// You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
userInfo, err := thirdparty.GetUserByID(userID)
if err != nil {
// TODO: Handle error
return
}
if userInfo == nil {
// no third party user exists with the id, so now we check email password user instead
emailPasswordUserInfo, err := emailpassword.GetUserByID(userID)
if err != nil {
// TODO: Handle error
return
}
fmt.Println(emailPasswordUserInfo)
} else {
fmt.Println(userInfo)
}
}
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/supertokens/supertokens-golang/recipe/session"
"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
"github.com/supertokens/supertokens-golang/recipe/thirdparty"
"github.com/supertokens/supertokens-golang/recipe/emailpassword"
)
func main() {
router := gin.New()
router.GET("/getuserinfo", verifySession(nil), getUserInfoAPI)
}
func verifySession(options *sessmodels.VerifySessionOptions) gin.HandlerFunc {
return func(c *gin.Context) {
session.VerifySession(options, func(rw http.ResponseWriter, r *http.Request) {
c.Request = c.Request.WithContext(r.Context())
c.Next()
})(c.Writer, c.Request)
// we call Abort so that the next handler in the chain is not called, unless we call Next explicitly
c.Abort()
}
}
func getUserInfoAPI(c *gin.Context) {
sessionContainer := session.GetSessionFromRequestContext(c.Request.Context())
userID := sessionContainer.GetUserID()
// You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
userInfo, err := thirdparty.GetUserByID(userID)
if err != nil {
// TODO: Handle error
return
}
if userInfo == nil {
// no third party user exists with the id, so now we check email password user instead
emailPasswordUserInfo, err := emailpassword.GetUserByID(userID)
if err != nil {
// TODO: Handle error
return
}
fmt.Println(emailPasswordUserInfo)
} else {
fmt.Println(userInfo)
}
//...
}
import (
"fmt"
"net/http"
"github.com/go-chi/chi"
"github.com/supertokens/supertokens-golang/recipe/session"
"github.com/supertokens/supertokens-golang/recipe/thirdparty"
"github.com/supertokens/supertokens-golang/recipe/emailpassword"
)
func main() {
r := chi.NewRouter()
r.Get("/getuserinfo", session.VerifySession(nil, getUserInfoAPI))
}
func getUserInfoAPI(w http.ResponseWriter, r *http.Request) {
sessionContainer := session.GetSessionFromRequestContext(r.Context())
userID := sessionContainer.GetUserID()
// You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
userInfo, err := thirdparty.GetUserByID(userID)
if err != nil {
// TODO: Handle error
return
}
if userInfo == nil {
// no third party user exists with the id, so now we check email password user instead
emailPasswordUserInfo, err := emailpassword.GetUserByID(userID)
if err != nil {
// TODO: Handle error
return
}
fmt.Println(emailPasswordUserInfo)
} else {
fmt.Println(userInfo)
}
}
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
"github.com/supertokens/supertokens-golang/recipe/session"
"github.com/supertokens/supertokens-golang/recipe/thirdparty"
"github.com/supertokens/supertokens-golang/recipe/emailpassword"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/getuserinfo", session.VerifySession(nil, getUserInfoAPI)).Methods(http.MethodGet)
}
func getUserInfoAPI(w http.ResponseWriter, r *http.Request) {
sessionContainer := session.GetSessionFromRequestContext(r.Context())
userID := sessionContainer.GetUserID()
// You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
userInfo, err := thirdparty.GetUserByID(userID)
if err != nil {
// TODO: Handle error
return
}
if userInfo == nil {
// no third party user exists with the id, so now we check email password user instead
emailPasswordUserInfo, err := emailpassword.GetUserByID(userID)
if err != nil {
// TODO: Handle error
return
}
fmt.Println(emailPasswordUserInfo)
} else {
fmt.Println(userInfo)
}
}
- FastAPI
- Flask
- Django
from supertokens_python.recipe.session.framework.fastapi import verify_session
from supertokens_python.asyncio import get_user
from supertokens_python.recipe.session import SessionContainer
from fastapi import FastAPI, Depends
app = FastAPI()
@app.post('/get_user_info_api')
async def get_user_info_api(session: SessionContainer = Depends(verify_session())):
user_id = session.get_user_id()
user = await get_user(user_id)
print(user)
from supertokens_python.recipe.session.framework.flask import verify_session
from supertokens_python.syncio import get_user
from flask import Flask, g
from supertokens_python.recipe.session import SessionContainer
app = Flask(__name__)
@app.route('/get_user_info', methods=['GET'])
@verify_session()
def get_user_info_api():
session: SessionContainer = g.supertokens
user_id = session.get_user_id()
user = get_user(user_id)
print(user)
from supertokens_python.recipe.session.framework.django.asyncio import verify_session
from supertokens_python.asyncio import get_user
from django.http import HttpRequest
from supertokens_python.recipe.session import SessionContainer
@verify_session()
async def get_user_info_api(request: HttpRequest):
session: SessionContainer = request.supertokens
user_id = session.get_user_id()
user = await get_user(user_id)
print(user)
#
Using the user metadata recipeCheckout the user metadata recipe docs which shows you how to save and fetch any JSON object against the user's ID. You can use this to save information like the user's name (first_name
and last_name
) or any other field associated with the user.
#
Getting information from the user's sessionThe user's session contains their user ID and the session's payload. You can access this on the backend and frontend as well as whilst the user is online or offline.
More information about this can be found in the session docs.
#
Getting the user's third party provider information and access tokenIf the user used a third party provider to login, you can access their info via SuperTokens as shown below. You can then save the OAuthTokens in your own db or in SuperTokens (using the user metadata recipe) and use them to fetch / change info about the logged in user from the third party provider.
- NodeJS
- GoLang
- Python
- Other Frameworks
Important
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";
import Session from "supertokens-node/recipe/session";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
supertokens: {
connectionURI: "...",
},
recipeList: [
ThirdParty.init({
override: {
functions: (originalImplementation) => {
return {
...originalImplementation,
// override the thirdparty sign in / up API
signInUp: async function (input) {
// TODO: Some pre sign in / up logic
let response = await originalImplementation.signInUp(input);
if (response.status === "OK") {
// This is the response from the OAuth tokens provided by the third party provider
let accessToken = response.oAuthTokens["access_token"];
// other tokens like the refresh_token or id_token are also
// available in the oAuthTokens object.
// This gives the user's info as returned by the provider's user profile endpoint.
let firstName = response.rawUserInfoFromProvider.fromUserInfoAPI!["first_name"];
// This gives the user's info from the returned ID token
// if the provider gave us an ID token
let lastName = response.rawUserInfoFromProvider.fromUserInfoAPI!["last_name"];
}
return response;
}
}
}
}
}),
Session.init({ /* ... */ })
]
});
import (
"fmt"
"github.com/supertokens/supertokens-golang/recipe/thirdparty"
"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
"github.com/supertokens/supertokens-golang/supertokens"
)
func main() {
supertokens.Init(supertokens.TypeInput{
RecipeList: []supertokens.Recipe{
thirdparty.Init(&tpmodels.TypeInput{
Override: &tpmodels.OverrideStruct{
Functions: func(originalImplementation tpmodels.RecipeInterface) tpmodels.RecipeInterface {
originalThirdPartySignInUp := *originalImplementation.SignInUp
// override the thirdparty sign in / up function
(*originalImplementation.SignInUp) = func(thirdPartyID, thirdPartyUserID, email string, oAuthTokens tpmodels.TypeOAuthTokens, rawUserInfoFromProvider tpmodels.TypeRawUserInfoFromProvider, tenantId string, userContext supertokens.UserContext) (tpmodels.SignInUpResponse, error) {
resp, err := originalThirdPartySignInUp(thirdPartyID, thirdPartyUserID, email, oAuthTokens, rawUserInfoFromProvider, tenantId, userContext)
if err != nil {
return tpmodels.SignInUpResponse{}, err
}
if resp.OK != nil {
user := resp.OK.User
fmt.Println(user)
// This is the response from the OAuth tokens provided by the third party provider
fmt.Println(resp.OK.OAuthTokens["access_token"])
// other tokens like the refresh_token or id_token are also
// available in the OAuthTokens object.
// This gives the user's info as returned by the provider's user profile endpoint.
fmt.Println(resp.OK.RawUserInfoFromProvider.FromUserInfoAPI["first_name"])
// This gives the user's info from the returned ID token
// if the provider gave us an ID token
fmt.Println(resp.OK.RawUserInfoFromProvider.FromIdTokenPayload["first_name"])
}
return resp, err
}
return originalImplementation
},
},
}),
},
})
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty.interfaces import (
APIInterface,
APIOptions,
SignInUpPostOkResult,
)
from typing import Optional, Union, Dict, Any
from supertokens_python.recipe.session.interfaces import SessionContainer
from supertokens_python.recipe.thirdparty.provider import Provider, RedirectUriInfo
def override_thirdparty_apis(original_implementation: APIInterface):
original_thirdparty_sign_in_up_post = original_implementation.sign_in_up_post
async def thirdparty_sign_in_up_post(
provider: Provider,
redirect_uri_info: Optional[RedirectUriInfo],
oauth_tokens: Optional[Dict[str, Any]],
session: Optional[SessionContainer],
should_try_linking_with_session_user: Union[bool, None],
tenant_id: str,
api_options: APIOptions,
user_context: Dict[str, Any],
):
# call the default behaviour as show below
result = await original_thirdparty_sign_in_up_post(
provider,
redirect_uri_info,
oauth_tokens,
session,
should_try_linking_with_session_user,
tenant_id,
api_options,
user_context,
)
if isinstance(result, SignInUpPostOkResult):
print(result.user)
# This is the response from the OAuth tokens provided by the third party provider
print(result.oauth_tokens["access_token"])
# other tokens like the refresh_token or id_token are also
# available in the OAuthTokens object.
# This gives the user's info as returned by the provider's user profile endpoint.
if result.raw_user_info_from_provider.from_user_info_api is not None:
print(
result.raw_user_info_from_provider.from_user_info_api["first_name"]
)
# This gives the user's info from the returned ID token
# if the provider gave us an ID token
if result.raw_user_info_from_provider.from_id_token_payload is not None:
print(
result.raw_user_info_from_provider.from_id_token_payload[
"first_name"
]
)
return result
original_implementation.sign_in_up_post = thirdparty_sign_in_up_post
return original_implementation
init(
app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
framework="...",
recipe_list=[
thirdparty.init(
override=thirdparty.InputOverrideConfig(apis=override_thirdparty_apis)
)
],
)