Descripción general
Laravel Bluesky admite dos métodos de autenticación. Las llamadas a la API tras autenticarse son comunes en ambos.
| Elemento | App Password | OAuth |
|---|
| Clases internas | LegacyAgent / LegacySession | OAuthAgent / OAuthSession |
| Punto de entrada | Bluesky::login() | Bluesky::withToken(OAuthSession) |
| Clave privada | No necesaria | Se requiere BLUESKY_OAUTH_PRIVATE_KEY |
| Autorización del usuario | No necesaria | Necesaria (aprobación en el navegador) |
| Ejecución en segundo plano | ✅ Muy adecuada | ✅ Posible (guardando refresh_token) |
| Claves de sesión | accessJwt / refreshJwt | access_token / refresh_token |
| Desaprobación | Ninguna | — |
| Usos principales | Publicaciones automáticas, notificaciones, procesos por lotes | Actuar en nombre del usuario, integración con Socialite |
El nombre LegacyAgent significa “método de autenticación anterior a OAuth”, pero App Password en sí no está marcado como obsoleto. En escenarios sin interacción del usuario, como notificaciones o publicaciones automáticas, App Password suele ser más sencillo y adecuado.
Arquitectura
BlueskyManager es la implementación real del Facade Bluesky. Configuras un agente con login() o withToken() y, a partir de ahí, las llamadas a la API usan los mismos métodos en cualquiera de los dos métodos de autenticación.
App Password (LegacyAgent)
Flujo de autenticación
Bluesky::login()
Solo tienes que configurar el App Password en .env y llamar a login().
BLUESKY_IDENTIFIER=your-handle.bsky.social
BLUESKY_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx
use Revolution\Bluesky\Facades\Bluesky;
$response = Bluesky::login(
identifier: config('bluesky.identifier'),
password: config('bluesky.password'),
)->post('Hello Bluesky');
Reutilizar LegacySession
Llamar a login() cada vez implica una petición a la API en cada ocasión. Cachear la sesión y reutilizarla es más eficiente.
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\LegacySession;
// Login inicial y guardado de la sesión
Bluesky::login(
identifier: config('bluesky.identifier'),
password: config('bluesky.password'),
);
cache()->put('bluesky_session', Bluesky::agent()->session()->toArray(), now()->addDay());
// A partir de aquí, restaura desde la caché
$session = LegacySession::create(cache('bluesky_session', []));
Bluesky::withToken($session);
// Si el access token ha caducado, refréscalo
if (! Bluesky::check()) {
Bluesky::refreshSession();
}
$response = Bluesky::post('Hello from cached session');
Claves principales de LegacySession
| Clave | Contenido | Método |
|---|
accessJwt | Access token | token() |
refreshJwt | Refresh token | refresh() |
did | DID de Bluesky | did() |
handle | Handle | handle() |
email | Correo electrónico | email() |
active | Si la cuenta está activa | active() |
Casos de uso adecuados
- Publicaciones automáticas en jobs de segundo plano y en la cola
- Notificaciones mediante los canales de Laravel Notification
- Procesos por lotes y tareas programadas
- Publicar desde la propia cuenta de la aplicación
OAuth (OAuthAgent)
Flujo de autenticación
Bluesky::withToken()
Pasas a withToken() el OAuthSession obtenido con Socialite.
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\OAuthSession;
// Restaurar desde la sesión de Laravel (petición web)
$session = OAuthSession::create(session('bluesky_session'));
$timeline = Bluesky::withToken($session)->getTimeline();
Incluso en jobs de segundo plano o en la consola, puedes construir OAuthSession a partir de valores guardados en la base de datos.
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\OAuthSession;
$session = OAuthSession::create([
'did' => $user->did,
'refresh_token' => $user->refresh_token,
// Para cuentas que no son de bsky.social, indica también iss
// 'iss' => $user->iss,
]);
$response = Bluesky::withToken($session)
->refreshSession()
->post('Hello from OAuth');
Claves principales de OAuthSession
| Clave | Contenido | Método |
|---|
access_token | Access token | token() |
refresh_token | Refresh token (usable una sola vez) | refresh() |
did / sub | DID de Bluesky | did() |
iss | URL del servidor de autorización | issuer() |
profile.handle | Handle | handle() |
profile.displayName | Nombre mostrado | displayName() |
El refresh_token de OAuth solo se puede usar una vez. Usa el evento OAuthSessionUpdated para actualizar siempre la base de datos tras un refresh de tokens. Consulta los detalles en Socialite.
Casos de uso adecuados
- Login de usuarios mediante Socialite
- Operaciones a la API en nombre del usuario
- Cuando cada usuario debe operar con una cuenta distinta
Las llamadas a la API tras autenticarse son comunes
Con cualquiera de los dos métodos de autenticación, tras withToken() se utilizan los mismos métodos de la API.
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\LegacySession;
use Revolution\Bluesky\Session\OAuthSession;
// App Password
Bluesky::login(config('bluesky.identifier'), config('bluesky.password'));
// O bien OAuth
$session = OAuthSession::create(session('bluesky_session'));
Bluesky::withToken($session);
// ↓ A partir de aquí, las llamadas a la API son completamente comunes ↓
Bluesky::post('Hello Bluesky');
Bluesky::getTimeline();
Bluesky::getProfile();
Bluesky::searchPosts(q: '#laravel');
BlueskyManager alterna internamente entre LegacyAgent y OAuthAgent, pero el código que llama a la API no se ve afectado.
¿Cuál elegir?
| Situación | Recomendación |
|---|
| Publicaciones automáticas, notificaciones, lotes | App Password |
| Función de login de usuarios | OAuth |
| Solo jobs de segundo plano | App Password |
| Necesidad de actuar en nombre del usuario | OAuth |
| Prioridad a la simplicidad operativa | App Password |
| Prioridad a seguridad y control de permisos | OAuth |
Cuando dudes, lo más claro es distinguir por el objetivo. Si “la aplicación actúa por sí sola”, usa App Password; si “el usuario opera”, usa OAuth. También es habitual combinar ambos: App Password para notificaciones y OAuth para el login de usuarios.
Enlaces de referencia