使用 Account Management API 手动关联 OAuth 提供方¶
Management API 提供了一种方式,让您能用自己的自定义界面来完成通常需要通过默认 /settings 页面才能完成的操作。
用于 OAuth 提供方的 Account Management API¶
用于 OAuth 提供方的 account management API 允许开发者编写自己的自定义代码,把社交或企业(OAuth)提供方关联到自己 Authany 项目下的用户账号上。开发者可以使用这个 API 创建自定义界面,让用户用它把一个或多个社交登录提供方关联到自己的账号。
用于 OAuth 提供方的 account management API 有 2 个端点,您的代码必须向它们发起 HTTP(s) POST 请求。以下是这两个端点的详细说明:
1. /api/v1/account/identification¶
使用这个端点发起把 OAuth 提供方关联到账号的流程。该端点要求在 Bearer Authorization 头中提供当前用户的有效访问令牌。
请求方法:
POST
请求头:
请求体:
{
"identification": "oauth",
"alias": "google",
"redirect_uri": "http://localhost:3000/linkcallback",
"exclude_state_in_authorization_url": false
}
identification:必填。值必须为oauth。alias:必填。您希望当前账号关联的 OAuth 提供方的别名。redirect_uri:必填。您需要指定自己应用或网站的重定向 URI,用于接收 OAuth 回调。exclude_state_in_authorization_url:可选。默认值为false。当为false时,authorization_url中会包含state参数,令牌会与该state参数绑定。当为true时,authorization_url中不包含state参数,令牌不会与state绑定。如果您希望使用自己的 state,必须将该字段设为true。
响应:
{
"result": {
"token": "oauthtoken_abc123xyz",
"authorization_url": "https://www.google.com?client_id=client_id&redirect_uri=redirect_uri"
}
}
token:您需要存储这个令牌。当终端用户返回您的应用后,需要提供这个令牌。authorization_url:您必须把终端用户重定向到这个 URL,以继续授权码流程。如果exclude_state_in_authorization_url为 false,该 URL 中会包含state参数。
2. /api/v1/account/identification/oauth¶
从您的重定向 URI 调用这个端点,以完成关联 OAuth 提供方的流程。
请求方法:
POST
请求头:
请求体:
token:您在 /api/v1/account/identification 端点的响应中收到的令牌。query:重定向 URI 中的 query。
响应:
如何关联 OAuth 提供方¶
在这个示例中,我们将以 Google 作为 OAuth 提供方进行关联。
步骤 1:用户登录(获取访问令牌)¶
account management API 需要用户有效的访问令牌才能工作。因此,您必须先对用户进行一次身份验证。
设置您的应用,让用户可以使用 Authany 登录并获取访问令牌。
有关您所使用的编程语言或框架的详细指南,请参见我们的开始使用部分。
步骤 2:发起 OAuth 关联流程¶
现在您的应用已经能为用户获取有效的访问令牌,接下来您将向 /api/v1/account/identification 端点发起 HTTP(s) 请求,以发起 OAuth 提供方关联流程。
使用以下代码发送 HTTP(s) 请求:
app.get("/link", async (req, res) => {
const endpoint = `<YOUR_AUTHGEAR_ENDPOINT>/api/v1/account/identification`;
const accessToken = req.session.accessToken; //TODO Get access token for user here. The example retrieves the value stored in session cookies
try {
const initiateAccountLink = await axios.post(endpoint,
{
"identification": "oauth",
"alias": "google",
"redirect_uri": `http://localhost:3000/linkcallback`,
"exclude_state_in_authorization_url": false
}, {
headers: { "Authorization": "Bearer " + accessToken }
});
req.session.token = initiateAccountLink.data.result.token;
res.send("linking initiated!"); // TODO Replace this link with Login with provider link instead
} catch(error) {
let errorInfo = error;
if (error.response) {
errorInfo = error.response.data;
}
res.send("An error occurred " + JSON.stringify(errorInfo));
}
});
在上面的代码中,HTTP(S) 请求体中的 identification 类型为 oauth,因为我们要把一个新的 OAuth 提供方添加为用户账号的一个身份。alias 的值为 google,因为要添加的 OAuth 提供方是 Google。
redirect_uri 中的链接是示例应用中的一个页面,用于处理来自 OAuth 提供方的回调。我们将在下一步实现这个页面。
/api/v1/account/identification 端点的响应应如下所示:
{
"result": {
"token": "oauthtoken_abc123xyz",
"authorization_url": "https://www.google.com?client_id=client_id&redirect_uri=redirect_uri"
}
}
步骤 3:获取 OAuth 提供方的授权 URL¶
步骤 2 中 HTTP(s) 请求的响应包含一个 authorization_url 字段。该字段包含 OAuth 提供方的授权 URL。您的应用可以把用户重定向到 authorization_url,让他们在 OAuth 提供方的网站上完成授权。
用以下代码替换步骤 2 中写有 // TODO 的那一行,将 authorization_url 的值用在一个用户可以点击的超链接中:
res.send(`
<a href="${initiateAccountLink.data.result.authorization_url}">Link Google Account</a>
`);
步骤 4:完成账号关联¶
关联 OAuth 提供方的最后一步,是实现 OAuth 提供方在授权完成后会把用户重定向回去的那个回调 URL。您的应用将在这里向第二个端点(/api/v1/account/identification/oauth)发起 HTTP(S) 请求。
在这个示例中,我们将创建一个 "/linkcallback" 路由,用以下代码处理这个重定向:
app.get('/linkcallback', async (req, res) => {
const endpoint = `<YOUR_AUTHGEAR_ENDPOINT>/api/v1/account/identification/oauth`;
const accessToken = req.session.accessToken;
const currentUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;
const queryParams = new URL(currentUrl).search;;
try {
const finishLink = await axios.post(endpoint, {
"token": req.session.token,
"query": queryParams,
},
{
headers: { "Authorization": "Bearer " + accessToken }
});
res.send(JSON.stringify(finishLink.data));
} catch(error) {
let errorInfo = error;
if (error.response) {
errorInfo = error.response.data;
}
res.send("An error occurred " + JSON.stringify(errorInfo));
}
});
以上代码把 token(上一次 HTTP(S) 请求响应中返回的值)以及 OAuth 提供方添加到重定向 URI 中的 query 参数,一起放在一个 HTTP(S) 请求中发送给完成端点。这两个参数都是必填的。
当 OAuth 提供方成功关联后,该端点的响应将如下所示: