Saltar al contenido principal

Autenticación Stellar

información

Esta guía está disponible en cuatro lenguajes de programación diferentes: Typescript, Kotlin, Flutter (Dart) y Swift. 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

Solo billeteras de custodia

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

const anchor = wallet.anchor({ homeDomain: "https://testanchor.stellar.org" });

A continuación, autentica con la authKey creada anteriormente:

const authKey = SigningKeypair.fromSecret("my secret key");
const sep10 = await anchor.sep10();

const authToken = await sep10.authenticate({ accountKp: authKey });

Para billeteras no custodiales, querrás usar la clave privada del usuario como authKey.

Dominio de origen (Opcional)

El dominio de origen 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 anclajes 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)

Solo billeteras no custodiales
advertencia

Algunos anclajes pueden requerir que el client_domain siempre esté presente como parte de la solicitud, incluso para billeteras no custodiales.

El dominio del cliente es utilizado por los anclajes para verificar el origen de la solicitud del usuario (¿qué billetera está usando este usuario?). Esto es particularmente útil para los anclajes para integrarse con billeteras no custodiales.

Admitir client_domain tiene dos partes, la implementación del cliente de la billetera y la implementación del servidor de la billetera. En esta configuración, tendremos una clave de autenticación adicional. Esta clave se almacenará de forma remota en el servidor. Usando el archivo de información SEP-1, el anclaje podrá consultar esta clave y verificar la firma. Así, el anclaje 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 signatario remoto que firma transacciones en el punto final https://demo-wallet-server.stellar.org/sign para el dominio del cliente demo-wallet-server.stellar.org.

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",
});
};
peligro

El punto final 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 suplantar al usuario de tu billetera.

Agreguemos autenticación con un token de portador. Simplemente actualiza el transformador de solicitudes:

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:

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 clave de autenticación del client_domain.

A continuación, crea un archivo toml SEP-1 colocado bajo <tu dominio>/.well-known/stellar.toml con el siguiente contenido:

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 secreta de la red para el despliegue en Mainnet.

Finalmente, agreguemos la implementación en el servidor. Esta implementación de ejemplo utiliza el framework express:

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 ambas implementaciones de billetera y servidor aquí. Como se mencionó antes, esta implementación de servidor de ejemplo no tiene ninguna protección contra solicitudes no autorizadas, así que debes agregar verificaciones de autorización como parte de la solicitud.