Authorization
Authorization vs authentication
Authorization controls what a user can access inside your app. Use it to differentiate subscription tiers (hobby vs pro) or to separate admins from regular users. Authentication verifies identity (logging in).
Client-side authorization
By default, LaunchPike lets everyone view the landing page (/) and restricts the rest (for example /demo-app and /account) to authenticated users. You control this per-page with authRequired in main.wasp
:
main.wasp
route AccountRoute { path: "/account", to: AccountPage }
page AccountPage {
authRequired: true,
component: import Account from "@src/user/AccountPage"
}
This automatically redirects non-logged-in visitors to the login page when they try to access protected pages.
Important note about client-side checks
Client code can be modified by users, so client-side authorization is for UX only. It keeps users from wandering into screens that will not work for them, but it does not protect data. Real protection happens on the server with authorization logic that checks access before returning data.
Fine-grained control on the client
If a page has authRequired: true
, Wasp passes the User
object to the component. You can branch the UI based on user properties:
ExamplePage.tsx import { type User } from "wasp/entities";
export default function Example({ user }: { user: User }) { if (user.subscriptionStatus === 'past_due') { return (<span>Your subscription is past due. Please update your payment information.</span>) } if (user.subscriptionStatus === 'cancel_at_period_end') { return (<span>Your susbscription will end on 01.01.2024</span>) } if (user.subscriptionStatus === 'active') { return (<span>Thanks so much for your support!</span>) } }
You can also use the useAuth
hook to read the current user and gate parts of a page or specific components:
ExamplePage.tsx
import { useAuth } from "wasp/client/auth";
export default function ExampleHomePage() {
const { data: user } = useAuth();
return (
<h1> Hi {user.email || 'there'} 👋 </h1>
)
}
</code></pre>
Server-side authorization
javascript
src/server/actions.ts
export const someServerAction: SomeServerAction<...> = async (args, context) => {
if (!context.user) {
throw new HttpError(401); // throw an error if user is not logged in
}
if (context.user.subscriptionStatus === 'past_due') {
throw new HttpError(403, 'Your subscription is past due. Please update your payment information.');
}
//...
}
</code></pre>
What’s next?
With login flows and server checks sorted, you’re ready for cookies : )