SAGE API 3.1, Laravel Socialite
Introducción
Hacía ya dos años y más que realice un trabajo para mi contabilidad que combinaba, WHMCS + SAGE + OVH + RedSys para así, ahorrarme más de 10000 apuntes al año.
Quería implementar Stripe, y de paso actualizar. Ay!!! Aquí vino el dolor. Desarrollos olvidados, tips y cosas que se quedan en el tintero. En su día, no había módulo de Laravel Socialite y todo lo que probé así que hice mi propia adaptación y todo iba bien en la actualización hasta que llegué aquí.
SAGE y OAuth 2
Instalar Socialite
composer require laravel/socialite
Después necesitamos el paquete de SAGE para Socialite (es muy simple y en caso de descontinuarse se puede continuar por uno mismo)
composer require socialiteproviders/sage
Importante leer el How to de ese módulo para entender que debemos configurar el listener que hay en EventServiceProvider
con el fín de que Socialite
escuche al módulo.
Comprobar las credenciales en SAGE
Esto me hizo perder el tiempo. Inexplicablemente pese a tener unas pocas modificaciones seguí manteniendo lo primordial, SAGE_CLIENT_ID
, SAGE_CLIENT_SECRET
, SAGE_REDIRECT_URL
, SAGE_STATE_CSRF
Sin embargo tras llegar a la página de autentificación de SAGE (no encuentro en su doc que permita una autenticación stateless o sin servidor web) el retorno fallaba.
Primero lo achaque a que como he dockerizado mi contabilidad, uso localhost, en lugar de un FQDN como en mi vieja raspberry, donde usaba un dominio falso midominio.test.
Pero, revisando se me olvido (siempre se olvida algo) en la página de Sage Development Portal hay que configurar la app y entre otras cosas están los callbacks autorizados.
Asi que hay que añadirlo http://localhost/login/sage/callback
Pero volvió a fallar.
¿Uhmm? Raro se me hace. Revisé las variables, y sorpresa… el SAGE_ID_CLIENT Y EL SAGE_CLIENT_SECRET no corresponden a las que me funcionan en la vieja raspberry. Vamos que mi vieja contabilidad está trabajando con unos datos obsoletos o que pertenecen a otra cuenta.
En fin, ahora sí.
Cómo usarlo en pocos pasos
.env
Los datos de cliente son los de la página del portal de desarrolladores
SAGE_CLIENT_ID=Client ID
SAGE_CLIENT_SECRET=’Client Secret’
SAGE_REDIRECT_URL=http://localhost/login/sage/callback
SAGE_STATE_CSRF=Token de al menos 32 caracteres aleatorio
Rutas
Es un ejemplo…
Route::get('/login/sage', [LoginController::class, 'redirectToSageProvider']);
Route::get('/login/sage/callback', [LoginController::class, 'handleProviderSageCallback']);
Controlador
En mi caso como hice mi propio paquete tengo un modelo en el que almaceno los tokens de proveedores externos de API que usan OAuth 2.0.
<?php
namespace App\Http\Controllers;
use Abkrim\ApiSage\Models\ExtToken;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Laravel\Socialite\Facades\Socialite;
class LoginController extends Controller
{
public function handleProviderSageCallback()
{
$auth_token = Socialite::driver('sage')->user(); // Fetch authenticated user
ExtToken::updateOrCreate(
[ 'driver' => 'sage' ],
[
'type' => 'bearer',
'scope' => 'full_access',
'access' => $auth_token->token,
'refresh' => $auth_token->refreshToken,
'access_expires' => Carbon::now()->addSeconds($auth_token->expiresIn),
'refresh_expires' => Carbon::now()->addSeconds($auth_token->accessTokenResponseBody['refresh_token_expires_in'])
]
);
return redirect()->to('/dondequeira');
}
public function redirectToSageProvider()
{
return Socialite::driver('sage')->redirect();
}
}
Es curioso que el retorno me devuelva un objeto en el que puedo consultar todo menos el token de refresco que tengo que ir a por él en un objeto que es una array en el que establos mismo datos más ese token.
Espero que te sirva, si llegaste aquí, porque estas cosas no suelen estar escritas por ahí.
Aviso
Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de Castris
Si necesitas soporte profesional puedes contratar con Castris soporte profesional.