Authorization

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:

javascript

    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:

javascript

    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:

javascript

        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 : )