This document presents the problem of authenticating requests in http servers at Decentraland. It presents two alternatives: Ephemeral keys or Private keys. Ephemeral keys are decided to improve the user experience to not require N interactions on the wallet.
We want to integrate our dApps with the explorer in order to provide a better experience for our users. To do so we need to send request authenticated by the user's wallet.
Ask the user to sign each request
Use
decentraland-crypto
as intermediary to sign each request
The option to use
decentraland-crypto
to interact with our services was chosen in order to provide a better experience to our users
In order to minimize the reutilization of request each payload must include data about the request and the moment it is made
/**
* Request method
*/
const METHOD: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" = `POST`
/**
* request path without domain, query string or hash
* @example
* - `/ping`
* - `new URL('https://decentraland.org/ping').pathname`
*/
const PATH: string = `/ping`
/**
* request timestamp
* each service decide how long it will consider valid a request using this timestamp,
* if timestamp is greater than now the request should fail
*/
const TIMESTAMP: number = Date.now()
/**
* request metadata
* can include extra data about the service that is making the request
* shouldn't contains data required to make the request, if it is empty
* and empty object should be use
*/
const METADATA: string = JSON.stringify({
/* extra data */
})
/**
* Payload
*/
const payload = [METHOD, PATH, TIMESTAMP, METADATA].join(":").toLowerCase()
Once you have an Identity from
decentraland-crypto
use signPayload
to get an AuthLink
import { Authenticator } from "decentraland-crypto"
const auth = await Authenticator.signPayload(identity, data)
To sign a request the AuthChain
should be included as a header in the request
along with the timestamp and the metadata
fetch("https://decentraland.org/ping", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Identity-Auth-Chain-0": JSON.stringify(auth[0]),
"X-Identity-Auth-Chain-1": JSON.stringify(auth[1]),
"X-Identity-Auth-Chain-2": JSON.stringify(auth[2]),
"X-Identity-Timestamp": TIMESTAMP,
"X-Identity-Metadata": METADATA
},
body: JSON.stringify({})
})