Secure user sessions, roles, and permissions—pre-configured using Better Auth.
Better Auth runs on a Drizzle adapter with a production ready setup. Email and password sign in, sessions, and role based access control are all included.
Good news: the core authentication pages are already done and integrated into the router. You don't need to build them from scratch.
They're fully functional and wired up to the authentication client, so you can focus on building the actual application.
The main guard for protected routes is the isAuthenticated middleware. It's simple:
/sign-in (that's Links.signIn).user and token into the route context so your server functions can use them.All the session stuff is in src/features/auth/session.ts, which sits on top of the main session store (@/lib/session).
| Task | Core Function |
|---|---|
| Get current user/token | useAppSession() / getSessionUserOrRedirect |
| Save/Update session data | saveSessionUser(data) |
| Clear session (Log Out) | removeSessionUser() |
You'll mainly use the hasPermission middleware or the verifyPermission server action to check access.
hasPermission(permission): This is a TanStack Router middleware. It runs before the route/handler executes, checks the user's permissions, and sets an isPermitted: boolean flag in the context.withPermission(context, handler): A simple wrapper. It runs a secure handler function only if context.isPermitted is true.Look at this: Any secure server action, like
getRoles, uses this pattern:
.middleware([isAuthenticated, hasPermission({user: ["read"]})]).handler(async ({ context }) => withPermission(context, () => { /* safe action code goes here */ }))