您的后端使用 Passwordless.dev 私有 API 来发起密钥注册、验证登录、为最终用户获取密钥等。
对此 API 发出的所有请求都要求 标头中包含您的 API 私有机密 以进行身份验证。通过 JavaScript 客户端 中的方法向公共 API 发出的请求将需要您的 API 公钥 。
/register/token
请求
向 /register/token
端点发出的 POST
请求会为用户创建一个注册令牌 ,您的前端将使用该令牌来协商 WebAuth 凭据的创建。
请求正文至少必须包含 userId
和 username
,例如:
HTTP JS
复制 POST https://v4.passwordless.dev/register/token HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
Content-Type: application/json
{
"userId": "107fb578-9559-4540-a0e2-f82ad78852f7",
"username": "pjfry@passwordless.dev",
"displayname": "Philip J Fry",
}
复制 const apiUrl = "https://v4.passwordless.dev";
const payload = {
"userId": "107fb578-9559-4540-a0e2-f82ad78852f7", // WebAuthn 用户句柄,应由您的应用程序生成。最多 64 字节。
"username": "pjfry@passwordless.dev", // 用于显示目的,应帮助用户识别用户账户。
"displayname": "Philip J. Fry", // 账户的人性化名称。
"authenticatorType": "any", // WebAuthn 验证器附件模式。可以是 "any"(默认)、"platform"(触发特定于客户端设备的 Windows Hello、FaceID 或 TouchID 选项)或 "cross-platform"(触发如安全密钥等漫游选项)。
"userVerification": "preferred", // 依赖方是否要求对操作进行本地调用授权。可以是 "preferred"(默认)、"required" 或 "optional"。
"aliases": ["pjfry@passwordless.dev"], // 用户创建的标识符(如电子邮件)数组,用于引用 userId。
"aliasHashing": true // 别名在存储之前是否应进行哈希处理。默认为 true。
};
// 使用您的 API 私有机密将 payload POST 到 Passwordless.dev API。
const { token } = await fetch(apiUrl + "/register", {
method: "POST",
body: JSON.stringify(payload),
headers: { "ApiSecret": "myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4", "Content-Type": "application/json"}
}).then(r => r.json());
除了必需的参数之外,请求正文还可能包含其他参数,所有这些参数如下:
必填 。WebAuthn 用户句柄,应由您的应用程序生成。这用于识别您的用户(可以是数据库主键 ID 或 guid)。最多 64 字节。不应包含有关用户的 PII。
"107fb578-9559-4540-a0e2-f82ad78852f7"
必填 。用户账户标的人性化识符。它仅用于显示,帮助用户确定具有相似显示名称的用户账户之间的区别。在浏览器 UI 中使用,从不存储在服务器上。
账户的人性化名称,应由用户选择。在浏览器 UI 中使用,从不存储在服务器上。
WebAuthn 证书传递首选项。仅支持 "none"
(默认)。
WebAuthn 验证器附件模式。可以是 "any"
(默认)、"platform"
(触发特定于客户端设备的 Windows Hello、FaceID 或 TouchID 选项)或 "cross-platform"
(触发如安全密钥等漫游选项)。
如果为 true
,则创建客户端可发现凭据,无需用户名即可登录。
允许在身份验证时选择用户验证的首选项(生物识别、PIN 码等),可以是 "preferred"
(默认)、"required"
或 "discouraged"
。
注册令牌到期的时间戳 (UTC)。默认为当前时间 +120 秒。
userId 的别名数组,例如电子邮件或用户名。用于使用 signinWithAlias()
方法在客户端发起登录。别名对于 userId 必须是唯一的。默认为空数组 []
。
["pjfry@passwordless.dev"]
别名在存储之前是否应进行哈希处理。默认为 true
。
响应
成功后,/register/token
端点将创建一个以 json 格式返回的注册令牌,例如:
复制 { "token": "register_wWdDh02ItIvnCKT_02ItIvn..."}
您的前端将使用此注册令牌来协商 WebAuth 凭据的创建。
/signin/verify
请求
向 /signin/verify
端点发出的 POST
请求会解压身份验证令牌 ,该令牌必须通过在前端调用 .signinWith*()
方法来生成(了解更多 )并包含在请求正文中,例如:
HTTP JS
复制 POST https://v4.passwordless.dev/signin/verify HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
Content-Type: application/json
{
"token": "d5vzCkL_GvpS4VYtoT3..."
}
复制 const apiUrl = "https://v4.passwordless.dev";
// 从前端获取身份验证令牌。
const payload = { token: req.query.token };
// 使用您的 API 私有机密将身份验证令牌 POST 到 Passwordless.dev API。
const response = await fetch(apiUrl + "/signin/verify", {
method: "POST",
body: JSON.stringify(payload),
headers: { "ApiSecret": "myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4", "Content-Type": "application/json" }
});
Passwordless.dev 私有 API 将解压身份验证令牌以检查其合法性。
响应
成功后,/signin/verify
端点将返回一个成功的响应对象,例如:
复制 {
"success": true,
"userId": "123",
"timestamp": "3023-08-01T14:43:03Z",
"rpid": "localhost",
"origin": "http://localhost:3000",
"device": "Firefox, Windows 10",
"country": "SE",
"nickname": "My Work Phone",
"expiresAt": "3023-08-01T14:43:03Z",
"tokenId": "TODO",
"type": "passkey_signin" // or passkey_register
}
使用 .success
值(true
或 false
)确定下一步操作,即是否完成登录(了解更多 )。
/signin/generate-token
请求
向 /signin/generate-token
端点发出的 POST
请求可为用户手动生成一个身份验证令牌,从而避开常规的登录流程(即 .signinWith*()
方法)。生成的令牌可以通过 /signin/verify
端点进行验证,并像普通身份验证令牌一样使用。
HTTP JS
复制 POST https://v4.passwordless.dev/signin/generate-token HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
Content-Type: application/json
{
"userId": "123"
}
复制 const apiUrl = 'https://v4.passwordless.dev';
// 生成身份验证令牌,绕过通常的登录过程。
const payload = {
userId: '107fb578-9559-4540-a0e2-f82ad78852f7'
};
// 使用您的 API 私有机密将用户 ID POST 到 Passwordless.dev API。
const response = await fetch(apiUrl + '/signin/generate-token', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'ApiSecret': 'myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4',
'Content-Type': 'application/json'
}
});
相应
成功后,/signin/generate-token
端点将返回一个响应对象,例如:
复制 {
"token": "d5vzCkL_GvpS4VYtoT3..."
}
/alias
请求
向 /alias
端点发出的 POST
请求会根据他们的 userId
向用户添加别名(了解更多 ),以便允许使用其他用户名、电子邮件地址等登录。
请求正文必须包含 用户的 userId
和完整的 别名数组,因为发出 POST
请求时预先存在的别名将被覆盖,例如:
HTTP JS
复制 POST https://v4.passwordless.dev/alias HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
Content-Type: application/json
{
"userId": "107fb578-9559-4540-a0e2-f82ad78852f7",
"aliases": [
"pjfry@passwordless.dev",
"benderrules@passwordless.dev"
],
"hashing": true
}
复制 const apiUrl = "https://v4.passwordless.dev";
// 获取用户现有的和新的别名数组。
const payload = {
"userId": "107fb578-9559-4540-a0e2-f82ad78852f7",
"aliases": ["pjfry@passwordless.dev", "benderrules@passwordless.dev"],
"hashing": true // 存储前是否对别名进行哈希处理,默认为 true。
};
// 使用您的 API 私有机密将数组 POST 到 Passwordless.dev API。
await fetch(apiUrl + "/alias", {
"method": "POST",
"body": JSON.stringify(payload),
"headers": { "ApiSecret": "myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4", "Content-Type": "application/json"}
});
默认情况下,"hashing": true
将在存储别名之前打开,以对其进行哈希处理。您将无法在管理控制台中查看已哈希的别名。
允许用户创建别名时需要考虑的一些规则:
一个 userId
最多可以有 10 个与其关联的别名。
响应
任何 API 响应中都不会返回别名,并且可以对其进行哈希处理以保护用户隐私(见上文)。成功后,/alias
端点将返回 HTTP 200 OK 状态代码 。
/credentials/list
请求
向 /credentials/list
端点发出的 GET
请求会列出与用户关联的所有已注册凭据 (由 userId
指定)。请求必须包含 相关的 userId
,例如:
HTTP JS
复制 GET https://v4.passwordless.dev/credentials/list?userId=107fb578-9559-4540-a0e2-f82ad78852f7 HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
复制 const apiUrl = "https://v4.passwordless.dev";
// 获取相关用户的 userId。
const payload = {
"userId": "107fb578-9559-4540-a0e2-f82ad78852f7"
};
// 使用您的 API 私有机密将 userId POST 到 Passwordless.dev API。
const credentials = await fetch(apiUrl + "/credentials/list", {
"method": "POST",
"body": JSON.stringify(payload),
"headers": { "ApiSecret": "myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4", "Content-Type": "application/json"}
}).then(r => r.json());
响应
成功后, /credentials/list
端点将返回 .json
对象数组,其中每个对象代表一个已注册的凭据 :
复制 [
{
"descriptor": {
"type": "public-key",
"id": "2mgrJ6LPItfxbnVc2UgFPHowNGKaYBm3Pf4so1bsXSk"
},
"publicKey": "pQECAyYgASFYIPi4M0A+ZFeyOHEC9iMe6dVhFnmOZdgac3MRmfqVpZ0AIlggWZ+l6+5rOGckXAsJ8i+mvPm4YuRQYDTHiJhIauagX4Q=",
"userHandle": "YzhhMzJlNWItNDZkMy00ODA4LWFlMTAtMTZkM2UyNmZmNmY5",
"signatureCounter": 0,
"createdAt": "2023-04-21T13:33:50.0764103",
"aaGuid": "adce0002-35bc-c60a-648b-0b25f1f05503",
"lastUsedAt": "2023-04-21T13:33:50.0764103",
"rpid": "myapp.example.com",
"origin": "https://myapp.example.com",
"country": "US",
"device": "Chrome, Mac OS X 10",
"nickname": "Fred's Macbook Pro 2",
"userId": "c8a32e5b-46d3-4808-ae10-16d3e26ff6f9"
} //, ...
]
详细了解这些键值对的含义 。
/credentials/delete
请求
向 /credentials/delete
端点发出的 POST
请求会删除与用户关联的特定凭证(由 credentialId
指定)。该请求必须包含 相关的 credentialId
,例如:
复制 POST https://v4.passwordless.dev/credentials/delete HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
Content-Type: application/json
{
"credentialId": "qgB2ZetBhi0rIcaQK8_HrLQzXXfwKia46_PNjUC2L_w"
}
响应
成功后,/credentials/delete
端点将返回 HTTP 200 OK 状态代码 。
/magic-links/send
请求
向 /magic-links/send
端点发出的 POST
请求会通过 Magic Link 向提供的地址发送电子邮件。此 Magic Link 包含您提供的 URL,该 URL 会将收件人重定向到您的应用程序中的端点。从这里,您可以发送 Passwordless.dev 嵌入链接中的令牌来验证 signin/verify
处的令牌。
Passwordless.dev 不存储用户电子邮件。集成 Magic Links 时,您应该验证电子邮件和用户 ID 是否属于同一用户。否则,您可能会在应用程序中引入安全漏洞。
该请求必须包含所有三个字段。
emailAddress
:Magic Link 的接收者。必须是一个有效的 E-mail 地址。
urlTemplate
:这是用户单击链接时将被定向到的 URL。它应该是除令牌模板字符串 $TOKEN
之外的有效 URL。在发送电子邮件之前,我们会将 $TOKEN
与实际令牌值交换。在您的应用程序中,您应该从 URL 中解析令牌(最容易通过查询参数完成,如下所示)并将其发送到 signin/verify
端点以验证请求。
timeToLive
:(可选)魔术链接令牌有效的秒数。如果未设置,则默认值为 1 小时。
复制 POST https://v4.passwwordless.dev/magic-links/send HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
Content-Type: application/json
{
"emailAddress": "user-email@example.com",
"urlTemplate": "https://www.myapp.com?token=$TOKEN"
"userId": "c8a32e5b-46d3-4808-ae10-16d3e26ff6f9"
"timeToLive": 3600
}
响应
如果成功, /magic-links/send
端点将返回 HTTP 204(无内容)状态代码 。
如果尚未启用 Magic Link, /magic-links/send
端点将返回 HTTP 403(未经授权)状态代码 以及有关启用 Magic Link 功能的消息。
/auth-configs/list
请求
向 /auth-configs/list
端点发出的 GET
请求将返回一个 .json
对象,其中包含应用程序可使用的身份验证配置列表。通过将目的名称作为查询参数,可以筛选出特定的配置。
复制 GET https://v4.passwordless.dev/auth-configs/list HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
复制 GET https://v4.passwordless.dev/auth-configs/list?purpose=step-up HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
有关身份验证配置的更多信息,请参阅概念页面 。
响应
如果成功,/auth-configs/list
端点将返回一个 .json
对象,其中包含一个身份验证配置列表:
复制 {
"configurations": [
{
"purpose": "sign-in",
"timeToLive": 120,
"userVerificationRequirement": "preferred",
"createdBy": "System",
"createdOn": null,
"editedBy": null,
"editedOn": null,
"lastUsedOn": null
},
{
"purpose": "step-up",
"timeToLive": 180,
"userVerificationRequirement": "required",
"createdBy": "System",
"createdOn": null,
"editedBy": null,
"editedOn": null,
"lastUsedOn": null
}
]
}
/auth-configs/add
请求
对 /auth-configs/add
的 POST
请求将为身份验证流程创建一个身份验证配置。请求对象有一些限制:
purpose
:A-z、0-9、- 和 _ 是允许使用的字符。其最大长度为 255 个字符。
timeToLive
:正向时间跨度值 (hh:mm:ss)
userVerificationRequirement
:preferred
,required
,discouraged
复制 GET https://v4.passwordless.dev/auth-configs/add HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
Content-Type: application/json
{
"purpose": "access-secrets-purpose", // identifying string give context to the specific authentication
"timeToLive": "00:03:00", // timespan the token is valid for
"userVerificationRequirement": "preferred", // requirement for if the user has to verify they're allowed to use an authenticator
"performedBy": "user_123" // user identifier to track changes to the configuration
}
响应
如果成功,/auth-configs/add
端点将返回 HTTP 201(已创建)状态代码 。
如果不成功,/auth-configs/add
端点将返回 HTTP 400(错误请求)状态代码 ,并附带问题详情信息 正文。
/auth-configs/
请求
对 /auth-configs
的 POST
请求将编辑身份验证流程的身份验证配置。请求对象有一些限制:
purpose
:必须是现有的 purpose(如果在此传递新的 purpose,将返回 404)
timeToLive
:正时间跨度值 (hh:mm:ss)
userVerificationRequirement
:preferred
,required
,discouraged
pedicatedBy
:用于跟踪配置更改的用户标识符
复制 GET https://v4.passwordless.dev/auth-configs HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
Content-Type: application/json
{
"purpose": "access-secrets-purpose", // existing purpose
"timeToLive": "00:03:00", // timespan the token is valid for
"userVerificationRequirement": "preferred", // requirement for if the user has to verify they're allowed to use an authenticator
"performedBy": "user_123" // user identifier to track changes to the configuration
}
响应
如果成功,/auth-configs
端点将返回 HTTP 204(无内容)状态代码 。
如果目的不明,/auth-configs
端点将返回 HTTP 404(未找到)状态代码 。
/auth-configs/delete
请求
向 /auth-configs/delete
端点发出的 POST
请求会删除特定的身份验证配置,该配置由 purpose
指定。
复制 GET https://v4.passwordless.dev/auth-configs/add HTTP/1.1
ApiSecret: myapplication:secret:11f8dd7733744f2596f2a28544b5fbc4
Content-Type: application/json
{
"purpose": "access-secrets-purpose", // existing purpose
"performedBy": "user_123" // user identifier to track changes to the configuration
}
响应
如果成功,/auth-configs/delete
端点将返回 HTTP 204(无内容)状态代码 。
如果目的不明,/auth-configs/delete
端点将返回 HTTP 404(未找到)状态代码 。
状态代码
API 会为每一个请求返回 HTTP 状态代码。
如果您收到错误,您还将收到问题详细信息 形式的 JSON 序列化的错误摘要。有关详细信息,请参阅错误页面 。