DEV Community

Kamran Khan
Kamran Khan

Posted on

My register endpoint returns a token — one fewer round trip, one better UX

Here's a small decision in my starter kit that I keep getting asked about: POST /api/auth/register returns a 201 with both the user object and an auth token. Not just "user created, now go log in." The user is authenticated the moment they register.

Why? Think about the actual flow. A new user fills in name, email, password, hits submit. If the response only confirms creation, the frontend has to immediately fire a second request to /api/auth/login with the same credentials, wait, get the token, store it, and then redirect. That's a round trip that serves no one — the server already validated everything it needs to validate. The register endpoint created the user; issuing a token for a user you just created is not a security hole, it's common sense.

The implementation is boring on purpose:

$user = User::create([
    'name'  => $request->validated('name'),
    'email' => $request->validated('email'),
    'password' => $request->validated('password'),
    'role'  => 'user',
]);

$token = $user->createToken('auth-token')->plainTextToken;

return response()->json([
    'user'  => new UserResource($user),
    'token' => $token,
], 201);
Enter fullscreen mode Exit fullscreen mode

Three things worth noticing. First, the role is hardcoded to 'user' — it comes from the server, not the request. The test suite literally posts role: admin and asserts the user is still created as a regular user. Second, the user goes through UserResource, so the shape the frontend receives on register is identical to login, /me, and every admin response — one contract, no surprises. Third, it's 201, because a resource was created. Status codes are part of the contract too; the frontend's error handling depends on them.

On the React side, this makes the register page trivial: post, store the token from the response, drop the user into context, navigate to the dashboard. No second request, no "please log in with the account you just created" awkwardness — which, honestly, always felt broken to me as a user. Every SaaS product you've ever signed up for logs you in immediately. Your starter kit should behave like the products you admire, not like a textbook.

And because the token issuance happens in the same request, there's one fewer place for the frontend to mishandle auth state. Fewer moving parts, fewer bugs. That's the whole philosophy: the boring path is usually the right one.


This is from my Laravel + React SaaS Starter Kit ($19, one-time) — Sanctum auth with register/login/logout/me, role-based access, and a React dashboard that consumes it all. The auth layer is done; you build the product.

Top comments (0)