Authany

Sign-in and user management for developers给开发者的登录与用户管理

We run the sign-in. You keep the brand.登录交给我们,品牌留给你

Hosted sign-up, sign-in and SSO. Your sign-in page lives at {project}.authanyid.com and wears your logo and colours. Your app connects over standard OpenID Connect; you manage users in the console.托管的注册、登录和单点登录。登录页在 {项目}.authanyid.com,用你的 Logo 和配色;你的应用用标准 OpenID Connect 接入,你在管理台里管理用户。

Read the docs阅读文档 Contact us联系我们

Sign-up isn’t open yet. To try it, email暂未开放注册。想先试用,发邮件到 hello@authany.com, with a line about your product.简单说说你的产品。

Example: a fictional company’s app sends the user to its own sign-in page on authanyid.com, and the user comes back to the app signed in, with an ID token.示例:一家虚构公司的应用把用户送到它自己在 authanyid.com 上的登录页,用户登录后带着 ID 令牌回到应用。

Example brand, fictional示例品牌(虚构)

Black line:Grey line: the part Authany runs黑线:灰线:Authany 在后台完成的部分

1 · Your app1 · 你的应用: the user taps Sign inThe user clicks Sign in, and your app redirects to /oauth2/authorize.:用户点「登录」用户点「登录」,你的应用跳转到 /oauth2/authorize。

2 · Your sign-in page2 · 你的登录页At {project}.authanyid.com, with your logo, colours and text.在 {项目}.authanyid.com 上,用你的 Logo、配色和文案。

3 · Back in your app3 · 回到你的应用, signed inThe user comes back with a code, which your app exchanges for an ID token. sub is the user’s ID in your project.,已登录用户带着授权码回来,你的应用把它换成 ID 令牌。sub 就是这个用户在你项目里的 ID。

  • Standard OpenID Connect标准 OpenID Connect
  • Google / Apple / GitHub / WeChat / passkeys微信 / Apple / Google / GitHub / 通行密钥
  • Console in English and Chinese管理台中英双语

01 · Sign-in page01 · 登录页

A sign-in page you never have to build.登录页,不用自己写。

Sign-up, sign-in, two-step verification, and brute-force and bot protection all happen on this one page. You set its look in the console.注册、登录、两步验证、防暴力破解和人机验证,都在这一页完成。外观在管理台里配置。

  1. Address地址{project}.authanyid.com, which is also the issuer your code expects.{项目}.authanyid.com,也就是你代码里的 issuer。
  2. Your brand你的品牌Logo, favicon, colours, the corner radius of buttons and inputs, light and dark theme, and the texts in each language.Logo、Favicon、颜色、按钮与输入框的圆角、浅色与深色主题,以及每种语言的文案。
  3. Sign-in methods登录方式After the email, a password, an email one-time code or a sign-in link. Or a passkey, with no email at all.输入邮箱后,用密码、邮箱验证码或登录链接;也可以不填邮箱,直接用通行密钥(Passkey)。
  1. Protection防护Brute-force protection, and bot protection with Cloudflare Turnstile or reCAPTCHA.暴力破解防护;机器人防护可用 Cloudflare Turnstile 或 reCAPTCHA。
  2. Social and enterprise sign-in社交与企业登录Google, Apple, GitHub, Facebook, LinkedIn, Microsoft Entra ID, Azure AD B2C, ADFS and WeChat (QR code on websites, and sign-in from your own iOS / Android app).微信(网站扫码登录;你自己的 iOS / Android App 拉起微信登录)、Apple、Google、GitHub、Facebook、LinkedIn、Microsoft Entra ID、Azure AD B2C 和 ADFS。
  3. Two-step verification and sessions两步验证与会话Authenticator apps (TOTP) with recovery codes, and session management.验证器 App(TOTP)加恢复码,以及会话管理。

02 · Integrate02 · 接入

Your code only needs to speak OpenID Connect.接入只要一个标准的 OIDC 库。

Any standard OIDC client library works: oidc-client-ts, openid-client, Authlib, go-oidc, AppAuth.任何标准的 OIDC 客户端库都能用:oidc-client-ts、openid-client、Authlib、go-oidc、AppAuth。

  1. Create a project and an application在管理台创建项目和应用

    Once you have an account, create both in the console. The project gives you an issuer, the application a client_id (and, for a Confidential Client, a client secret); add your callback URL.开通账号后在管理台里创建:项目给你 issuer,应用给你 client_id(机密客户端还有 client secret);再填好你的回调地址。

    issuer = https://{project}{项目}.authanyid.com

  2. Redirect to /oauth2/authorize跳转到 /oauth2/authorize

    Authorization code with PKCE. The user signs in on your page and comes back to your callback with a code.授权码流程加 PKCE。用户在你的登录页上登录,带着 code 回到你的回调地址。

    response_type=codecode_challenge_method=S256

  3. Exchange the code for tokens用 code 换取令牌

    At /oauth2/token. The sub in the ID token is the user’s ID in your project.在 /oauth2/token 用 code 换取令牌。ID 令牌里的 sub 就是这个用户在你项目里的 ID。

    subamrauth_timesid

For your backend: hooks on sign-up, sign-in and profile changes (blocking hooks can stop the action, non-blocking ones just notify you).后端集成:注册、登录、资料变更时触发 Hook(阻塞型可以拦下这次操作,非阻塞型只做通知)。

JavaScript · oidc-client-ts

import { UserManager } from "oidc-client-ts";

const auth = new UserManager({
  authority: "https://inkwell.authanyid.com",
  client_id: "<client_id>",
  redirect_uri: "https://inkwell.example/callback",
  scope: "openid",
});

// Sign-in button: to /oauth2/authorize, PKCE included// 登录按钮:跳到 /oauth2/authorize,PKCE 由库生成
document.getElementById("sign-in").onclick = () => auth.signinRedirect();

// On /callback: exchange the code for tokens// 回调页:用 code 换取令牌
const user = await auth.signinRedirectCallback();
console.log(user.profile.sub);

Node · openid-client

import * as oidc from "openid-client";

const config = await oidc.discovery(
  new URL("https://inkwell.authanyid.com"), "<client_id>", "<client_secret>");

// 1. Send the user to /oauth2/authorize with PKCE// 1. 带上 PKCE,跳到 /oauth2/authorize
const verifier = oidc.randomPKCECodeVerifier();
const url = oidc.buildAuthorizationUrl(config, {
  redirect_uri: "https://inkwell.example/callback",
  scope: "openid",
  code_challenge: await oidc.calculatePKCECodeChallenge(verifier),
  code_challenge_method: "S256",
});
// redirect the user to url.href; keep verifier in the session for step 2// 把用户重定向到 url.href;verifier 存进 session,第 2 步要用

// 2. Callback: exchange the code; the library checks the ID token’s claims// 2. 回调:用 code 换令牌,库会校验 ID 令牌的声明
const callbackUrl = new URL(req.url, "https://inkwell.example");
const tokens = await oidc.authorizationCodeGrant(config, callbackUrl,
  { pkceCodeVerifier: verifier });
console.log(tokens.claims().sub);

Python · Authlib

from flask import Flask, url_for
from authlib.integrations.flask_client import OAuth

app = Flask(__name__)
app.secret_key = "<random secret>"  # Authlib keeps PKCE state in the session# Authlib 把 PKCE 状态存在 session 里
ISSUER = "https://inkwell.authanyid.com"
oauth = OAuth(app)
oauth.register(
    "authany",
    server_metadata_url=f"{ISSUER}/.well-known/openid-configuration",
    client_id="<client_id>", client_secret="<client_secret>",
    client_kwargs={"scope": "openid", "code_challenge_method": "S256"},
)

@app.get("/login")  # to /oauth2/authorize, with PKCE# 跳到 /oauth2/authorize,带 PKCE
def login():
    return oauth.authany.authorize_redirect(url_for("callback", _external=True))

@app.get("/callback")  # exchanges the code, verifies the ID token# 换取令牌并校验 ID 令牌
def callback():
    token = oauth.authany.authorize_access_token()
    return token["userinfo"]["sub"]

03 · Ownership03 · 用户数据

Your users belong to your project.你的用户只属于你的项目。

Every project is its own user pool: the same email in three projects is three unrelated users, each with its own sub, credentials and status.每个项目都是独立的用户池:同一个邮箱在三个项目里,就是三个互不相干的用户,各有各的 sub、凭据和状态。

One person, one email同一个人,同一个邮箱lin@example.com

  • Inkwell Notes墨池笔记Example示例

    inkwell.authanyid.com

    sub
    9b2e71c4-3f5a-4d08-b6e2-71a0c9d4e85f
    Signs in with登录方式
    Password密码
    Status状态
    Active正常
  • Pixelforge Games像素工坊Example示例

    pixelforge.authanyid.com

    sub
    e41d7a93-0c6b-4f2e-9a57-2d8b13f6c0a4
    Signs in with登录方式
    Google
    Status状态
    Disabled已禁用
    Disabled here only. Lin still signs in to the other two.只在这个项目里禁用,另外两个照常登录。
  • Meadow Tea青禾茶饮Example示例

    meadow.authanyid.com

    sub
    57c0f3b8-a2d4-4e91-8b6f-c93e0d1a7b25
    Signs in with登录方式
    Email code邮箱验证码
    Status状态
    Active正常

Nothing links the three. One project cannot see another’s users.三者之间没有任何关联。一个项目看不到另一个项目的用户。

We run the sign-in. You keep the brand.登录交给我们,品牌留给你。

Read the docs阅读文档 Contact us联系我们

Sign-up isn’t open yet. To try it, email暂未开放注册。想先试用,发邮件到 hello@authany.com, with a line about your product.简单说说你的产品。