不使用 SDK 集成 Authany(客户端)¶
Authany 基于 OIDC 2.0 标准构建,您可以在不使用 SDK 的情况下,将其集成到任意应用框架中。
支持的授权类型¶
带 PKCE(Proof Key for Code Exchange)的授权码流程(Authorization Code Flow)
对于移动应用和 SPA 等公开客户端,应使用 PKCE 流程。该流程在身份验证请求中使用 code_challenge_method 和 code_challenge 参数,并在换取令牌步骤中使用 code_verifier 参数。这样可以确保发起授权码流程的应用,与完成该流程的应用是同一个。
OpenID Connect 配置¶
该端点会返回一个 JSON 文档,其中包含您 Authany 项目的 OpenID Connect 配置,包括授权端点、令牌端点和 JWKs 端点。URL 如下所示:
发起注册和登录¶
要进行注册或登录,请将用户重定向到 /authorize 端点。URL 如下所示:
https://AUTHGEAR_ENDPOINT/oauth2/authorize
?response_type=code
&client_id=CLIENT_ID
&redirect_uri=REDIRECT_URL
&scope=openid+offline_access+https://authany.com/scopes/full-userinfo
&code_challenge_method=S256
&code_challenge=CODE_CHALLENGE
&state=abc
代码示例
curl -X GET 'https://AUTHGEAR_ENDPOINT/oauth2/authorize' \
--data-urlencode 'response_type=code' \
--data-urlencode 'client_id=CLIENT_ID' \
--data-urlencode 'redirect_uri=REDIRECT_URL' \
--data-urlencode 'scope=openid offline_access https://authany.com/scopes/full-userinfo' \
--data-urlencode 'code_challenge_method=S256' \
--data-urlencode 'code_challenge=CODE_CHALLENGE' \
--data-urlencode 'state=abc'
const randomData = secureRandomBytes(32); // (1)
const code_verifier = base64url(randomData); // (2)
const hash = await sha256(utf8(code_verifier));
const code_challenge = base64url(hash);
// (1) A 32-byte long secure random data using secure random number generator
// (2) this string must be between 43 and 126 bytes long
const params = new URLSearchParams();
params.set("response_type", "code");
params.set("client_id", "CLIENT_ID");
params.set("redirect_uri", "REDIRECT_URL");
params.set("scope", ["openid", "offline_access", "https://authany.com/scopes/full-userinfo"].join(" "));
params.set("code_challenge_method", "S256");
params.set("code_challenge", code_verifier);
params.set("state", "abc");
const endpoint = new URL("https://AUTHGEAR_ENDPOINT/oauth2/authorize");
const authorizationURL = endpoint.toString() + "?" + params.toString();
- code_challenge_method 支持 “S256”。
code_verifier是在客户端生成的一个长度在 43 到 128 之间的字符串,每次授权请求都应该是唯一的。code_challenge是该 verifier 的 SHA-256 哈希值。- state 参数是可选的。Authany 会在将用户重定向回客户端应用时,带上该 state 参数的值。详见 使用 OAuth 2.0 State 参数
- 登录后,用户将被重定向到
[redirect_uri]?code=[AUTH_CODE],下一步需要用到该AUTH_CODE - 支持的作用域请参见 支持的作用域
处理回调¶
在您的应用中收到 AUTH_CODE 后,向 /token 端点发起 POST 请求。
const tokenEndpoint = new URL("https://AUTHGEAR_ENDPOINT/oauth2/token");
const form = new URLSearchParams();
form.set("grant_type", "authorization_code");
form.set("client_id", "CLIENT_ID");
form.set("code", AUTH_CODE); //Authorization code returned from authgear server
form.set("redirect_uri", "REDIRECT_URL");
form.set("code_verifier", code_verifier);
const response = await fetch(tokenEndpoint.toString(), {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: form,
});
const responseJSON = await response.json();
- 附上用于生成
code_challenge的code_verifier,以证明两次请求来自同一个客户端。 - 响应中可能包含 ID 令牌、访问令牌和刷新令牌,具体取决于上一步提供的
scope。
登出¶
当用户登出时,向 revocation_endpoint 发起 POST 请求以撤销刷新令牌,请求体中带上刷新令牌,content-type 使用 application/x-www-form-urlencoded。该端点形如 https://AUTHGEAR_ENDPOINT/oauth2/revoke,可以在 OpenID Connect 配置文档中找到。
然后清除应用本地存储的访问令牌和刷新令牌。
验证 JWT 访问令牌¶
在前端请求的 Authorization 请求头中带上访问令牌,以验证用户身份。请参阅本指南了解如何在应用服务器中验证 JWT:在后端验证 JWT