Autenticación Stellar
Esta guía está disponible en tres lenguajes de programación diferentes: Typescript, Kotlin y Flutter (Dart). Puedes cambiar la versión mostrada en cada página mediante los botones de arriba.
Las billeteras se conectan a los anchors utilizando una forma estándar de autenticación a través de la red Stellar definida por el estándar SEP-10.
Esta guía cubrirá todas las formas de usar SEP-10 para autenticarte con un anchor.
Crear una clave de autenticación
Primero, vamos a crear una clave de autenticación. Aunque puedes usar la misma clave para autenticación y enviar fondos, se recomienda dividir las responsabilidades. En tu aplicación, tendrás una o más keypairs de fondos (keypairs para las cuentas que mantienen fondos e inician y reciben transacciones) y una clave de autenticación.
La clave de autenticación solo se utiliza para propósitos de autenticación y no necesita mantener fondos. Ten en cuenta que no necesitas crear una cuenta para este keypair tampoco.
Ve a [Stellar Lab] y genera un keypair. La clave secreta debe manejarse de manera segura, porque se utilizará para la autenticación.
Autenticación básica
Hagamos una autenticación básica. En este ejemplo, utilizaremos el SDK de billetera para crear un token de autenticación.
Primero, vamos a crear un objeto anchor
para trabajar con el anchor con el que te estás integrando. En este ejemplo, utilizaremos una implementación de anchor de referencia con el dominio principal testanchor.stellar.org
- TypeScript
const anchor = wallet.anchor({ homeDomain: "https://testanchor.stellar.org" });
A continuación, autentícate con la authKey
creada anteriormente:
- TypeScript
const authKey = SigningKeypair.fromSecret("my secret key");
const sep10 = await anchor.sep10();
const authToken = await sep10.authenticate({ accountKp: authKey });
Para las billeteras no custodiales, deseas usar la clave privada del usuario como un authKey
.
Dominio principal (opcional)
El dominio principal es el parámetro opcional para la autenticación SEP-10, cuando un único servidor de autenticación se comparte entre múltiples dominios. Algunos anchors pueden requerir que proporciones este argumento. El SDK establece automáticamente el parámetro home_domain
en todas las solicitudes SEP-10.
Dominio del cliente (opcional)
Algunos anchors pueden requerir que el client_domain
esté siempre presente como parte de la solicitud, incluso para billeteras no custodiales.
El dominio del cliente es utilizado por los anchors para verificar el origen de la solicitud del usuario (¿qué billetera está utilizando este usuario?). Esto es particularmente útil para los anchors para integrarse con billeteras no custodiales.
El soporte para client_domain
se divide en dos partes, el cliente de la billetera y las implementaciones del servidor de la billetera. En esta configuración, tendremos una clave de autenticación extra. Esta clave se almacenará de forma remota en el servidor. Usando el archivo de información SEP-1, el anchor podrá consultar esta clave y verificar la firma. De este modo, el anchor podrá confirmar que la solicitud proviene de tu billetera, perteneciente al client_domain
de la billetera.
Lado del cliente
Primero, implementemos el lado del cliente. En este ejemplo, nos conectaremos a un firmante remoto que firma transacciones en el endpoint https://demo-wallet-server.stellar.org/sign
para el dominio del cliente demo-wallet-server.stellar.org
.
- TypeScript
const signer = new DomainSigner(
"https://demo-wallet-server.stellar.org/sign",
{},
);
const getAuthToken = async () => {
return anchor.sep10().authenticate({
accountKp,
walletSigner: signer,
clientDomain: "demo-wallet-server.stellar.org",
});
};
El endpoint de firma de demo-wallet no está protegido para que cualquiera lo use. Tu URL de producción debe estar protegida, de lo contrario, cualquiera podría hacerse pasar por el usuario de tu billetera.
Agreguemos autenticación con un token portador. Simplemente actualiza el transformador de solicitudes:
- TypeScript
const signer = new DomainSigner("https://demo-wallet-server.stellar.org/sign", {
Authorization: `Bearer ${authToken}`,
});
Finalmente, con el enfoque anterior definimos el firmante y el dominio del cliente por cada solicitud. Si deseas definirlo una vez y usarlo para cada llamada de autenticación que tu aplicación esté realizando, puedes hacerlo cambiando la configuración:
- TypeScript
const appCfg = new ApplicationConfiguration(
new DomainSigner("https://my-domain.com/sign", { ...headers }),
undefined,
"my-domain.com",
);
Esto es particularmente útil para integrar con múltiples anchors.
Lado del servidor
A continuación, implementemos el lado del servidor.
Primero, genera una nueva clave de autenticación que se usará como una clave de autenticación client_domain
.
Next, create a SEP-1
toml file placed under <your domain>/.well-known/stellar.toml
with the following content:
- TOML
ACCOUNTS = [ "Authentication public key (address)" ]
VERSION = "0.1.0"
SIGNING_KEY = "Authentication public key (address)"
NETWORK_PASSPHRASE = "Test SDF Network ; September 2015"
No olvides cambiar la frase de pase de red para el despliegue de Mainnet.
Finalmente, agreguemos la implementación del servidor. Esta implementación de muestra utiliza el framework express:
- JavaScript
app.post("/sign", (req, res) => {
const envelope_xdr = req.body.transaction;
const network_passphrase = req.body.network_passphrase;
const transaction = new Transaction(envelope_xdr, network_passphrase);
if (Number.parseInt(transaction.sequence, 10) !== 0) {
res.status(400);
res.send("transaction sequence value must be '0'");
return;
}
transaction.sign(Keypair.fromSecret(SERVER_SIGNING_KEY));
res.set("Access-Control-Allow-Origin", "*");
res.status(200);
res.send({
transaction: transaction.toEnvelope().toXDR("base64"),
network_passphrase: network_passphrase,
});
});
Puedes ver ejemplos de las implementaciones de billetera y servidor aquí. Como se mencionó anteriormente, esta implementación de ejemplo de servidor no tiene ninguna protección contra solicitudes no autorizadas, así que debes agregar verificaciones de autorización como parte de la solicitud.