跳转至

不使用 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 如下所示:

https://AUTHGEAR_ENDPOINT/.well-known/openid-configuration

发起注册和登录

要进行注册或登录,请将用户重定向到 /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 请求。

curl -X POST 'https://AUTHGEAR_ENDPOINT/oauth2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=authorization_code' \
-d 'client_id=CLIENT_ID' \
-d 'code=AUTH_CODE' \
-d 'redirect_uri=REDIRECT_URL' \
-d 'code_verifier=CODE_VERIFIER'
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