Authentication
How customer auth works on StoreOS — login, register, OTP, and sessions.
What auth does
Auth lets shoppers on your storefront create an account, sign in, and access their profile and order history. StoreOS stores customer records and issues a JWT (accessToken) your app sends on later requests.
Your app owns: login UI, saving the token (cookie, storage), protected routes.
StoreOS owns: password hashing, OTP SMS, customer database.
Headers
| Header | When |
|---|---|
x-tenant | Every request — which store |
Authorization: Bearer <access-token> | Logged-in actions (me, myOrders, cancelOrder, profile) |
JWTs last 7 days (aud: storefront, iss: storeos.dev).
Email / password
register
What it does: Creates a new customer with name, email and/or phone, password. Returns token — customer is logged in.
mutation Register($input: StorefrontRegisterInput!) {
register(input: $input) {
accessToken
user { _id name email phoneNumber }
}
}REST: POST /api/v1/auth/register · SDK: register()
login
What it does: Signs in an existing customer with email or phone + password.
mutation Login($input: StorefrontLoginInput!) {
login(input: $input) {
accessToken
user { _id name email phoneNumber }
}
}The user field accepts email or phone number.
REST: POST /api/v1/auth/login · SDK: login()
Phone OTP (Bangladesh)
What it does: Passwordless login via 4-digit SMS code — common for mobile-first storefronts.
| Step | Mutation | What happens |
|---|---|---|
| 1 | sendOtp | SMS sent; isNewCustomer tells you if name is needed |
| 2 | verifyOtpToLogin | Code checked; account created if new; token returned |
mutation SendOtp($input: SendOtpInput!) {
sendOtp(input: $input) { success message isNewCustomer }
}
mutation VerifyOtp($input: VerifyOtpInput!) {
verifyOtpToLogin(input: $input) {
accessToken
user { _id name phoneNumber }
}
}Use phoneNumber (not phone). New customers must pass name on verify.
After login — me
What it does: Returns the current customer from the JWT.
query Me {
me { _id name email phoneNumber }
}Auth required. Use to pre-fill checkout or show account page.
Session in your app
StoreOS JWTs are stateless — StoreOS does not manage browser sessions for you.
// With SDK
await store.login({ user: "jane@example.com", password: "…" });
const token = store.getAccessToken();
// → save to cookie / localStorage
store.setAccessToken(savedToken); // on next visitWith raw GraphQL, send Authorization: Bearer ${token} on every authenticated request.
REST & SDK equivalents
All flows exist at /api/v1/auth/*. Using @storeos/storefront-client avoids writing GraphQL by hand.