# Autenticación en el servidor

> Cliente confidencial, callback propio y tokens ligados a cada petición.


En el servidor tu aplicación es un cliente confidencial: tiene un secreto y lo usa para autenticarse ante Andco. La diferencia importante con el navegador no es el secreto, es que **la instancia no guarda sesión**. Cada petición trae la suya.

## Guías por framework

Esta página es el flujo genérico. Si usas alguno de estos, mejor parte de su guía:

- [Next.js · App Router](/docs/guides/nextjs-app-router)
- [Next.js · Pages Router](/docs/guides/nextjs-pages-router)
- [Hono](/docs/guides/hono)
- [Express](/docs/guides/express)
- [FastAPI](/docs/guides/fastapi)
- [Django](/docs/guides/django)

## Crear la instancia

```ts title="andco.server.ts"
import { createAndcoInstanceForServer } from "@andco/sdk/server";

export const andco = createAndcoInstanceForServer({
  clientId: process.env.ANDCO_CLIENT_ID!,
  clientSecret: process.env.ANDCO_CLIENT_SECRET!,
});
```

Esta instancia es compartida por todas las peticiones y no tiene `auth` ni `session`, porque no hay una sola persona detrás de ella. Tiene `oauth` para conducir el protocolo, y `with()` para ligar una credencial a una petición.

## Iniciar la autorización

```ts
const { data: request, error } = await andco.oauth.createAuthorizationRequest({
  redirectTo: "https://tuapp.com/auth/callback",
  scopes: ["openid", "email", "profile"],
});
```

`request` trae la URL a la que enviar a la persona, el `state` y el verificador PKCE. **Guarda el `request` completo** asociado a la sesión del navegador: lo vas a necesitar en el callback y el verificador no puede viajar en la URL.

```ts
session.andcoTransaction = request;
redirect(request.authorizationUrl.href);
```

## Recibir el callback

```ts
const { data: andcoSession, error } = await andco.oauth.exchangeCallback({
  callbackUrl: new URL(request.url),
  request: session.andcoTransaction,
});
```

`exchangeCallback` valida que el callback corresponda a esa transacción —origen, `state`, antigüedad— antes de intercambiar nada. Si algo no calza, devuelve error y no gasta el código.

Lo que hagas con la sesión resultante es tuyo: guardarla en tu propia sesión, en una base de datos o en una cookie firmada.

## Llamar a la API por cuenta de una persona

```ts
const rest = andco.with(andcoSession.accessToken).rest;
const { data, error } = await rest.http.GET("/accounts");
```

`with()` devuelve un cliente ligado, no muta la instancia. Eso es lo que impide que la credencial de una petición se filtre a otra.

Acepta tres formas, según lo que tengas a mano:

```ts
andco.with("a-bare-access-token");
andco.with(andcoSession); // a full session — same lookup, still no refresh
andco.with(myCredentials); // your own implementation
```

Ninguna de las dos primeras formas renueva por sí sola: son una consulta directa al token de la sesión, sin persistencia ni renovación. Solo `myCredentials` puede renovar, si tú se lo implementas — por ejemplo, resolviendo el token desde donde guardaste la sesión y renovando ahí cuando esté vencida.

## Renovar

```ts
const { data: refreshed, error } = await andco.oauth.refresh(andcoSession.refreshToken!);
```

Los refresh tokens rotan: el que recibes reemplaza al anterior y el anterior deja de servir. Guarda el nuevo.
