# Better Auth

> Read the Better Auth session in a middleware and type ctx.user with its user.

[Better Auth](https://better-auth.com/) reads the session from the request's headers. It needs no adapter package:

```package-install
@trpc12/trpc better-auth
```

Put the headers in the ctx, then a [middleware](https://v12.trpc.io/docs/server/middleware.md) turns the session into `ctx.user`:

```ts
const t = initTrpc<{ ctx: { headers: Headers } }>();

const authed = t.procedure.use(async (opts) => {
  const session = await auth.api.getSession({ headers: opts.ctx.headers });
  return session
    ? opts.next({ ctx: { user: session.user, session: session.session } })
    : error({ code: 'UNAUTHORIZED' });
});

const router = {
  me: authed.query((opts) => opts.ctx.user.name), // ctx.user is Better Auth's user type
};

createFetchHandler({
  router,
  createContext: (opts) => ({
    headers: new Headers(opts.request.headers as Record<string, string>),
  }),
});
```

- Same-origin browsers send Better Auth's session cookie with each call. From another origin, set `httpLink({ init: () => ({ credentials: 'include' }) })` and allow credentials in [CORS](https://v12.trpc.io/docs/adapters/overview.md#middleware-and-cors).
- Over WebSockets, `createContext` gets the upgrade request's headers, so the cookie works there too.
- Better Auth's own routes (`/api/auth/*`) stay on `auth.handler`; serve them next to the tRPC endpoint.
