跳转至

事件与 Hook

事件(Event)是关键操作发生时(例如新用户注册)您的 webhook 或 TypeScript hook 处理程序收到的实时通知。同一事件可以设置多个 Hook。

事件分为两种类型:阻塞(Blocking)和非阻塞(Non-blocking)。

非阻塞事件的投递顺序不确定。阻塞事件按照配置中的顺序投递。

在哪里为 Authany 项目创建 Hook

  • 在管理台中,进入 高级 > Hook。
  • 根据要监听的事件类型,在 阻塞事件(Blocking Events) 和 非阻塞事件(Non-Blocking Events) 中添加您的 Hook。
  • 点击 保存。

事件内容(Event Body)

事件的结构如下:

{
  "id": "0E1E9537-DF4F-4AF6-8B48-3DB4574D4F24",
  "seq": 435,
  "type": "user.pre_create",
  "payload": { /* ... */ },
  "context": {
    "app_id": "project-1",
    "client_id": "bfb2e0e0e7f3cfa2",
    "timestamp": 1670570552,
    "user_id": "f333b70b-4436-4efb-a40b-d9ed7a74d319",
    "preferred_languages": ["en-US", "zh-HK"],
    "language": "en-US",
    "triggered_by": "user",
    "oauth": {
      "state": "eyJ0b2tlbiI6IlgxS1RRTUM1TkRRUzQzOFAifQ"
    },
    "ip_address": "178.238.11.6",
    "geo_location_code": "GB",
    "user_agent": " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36",

  }
}
  • id:事件的 ID。
  • seq:单调递增的有符号 64 位整数。
  • type:事件的类型。
  • payload:事件的负载,随类型不同而不同。各事件的详细负载请参阅阻塞事件和非阻塞事件。
  • context:事件的上下文。

事件上下文(Event Context)

上下文内容提供了客户端的详细信息以及收集到的身份验证信号:

  • app_id:Authany 项目的 ID。
  • client_id:应用的客户端 ID(如果存在)。
  • timestamp:生成该事件时的有符号 64 位 UNIX 时间戳。重试投递不会影响该字段。
  • user_id:与事件关联的用户 ID,可能不存在,例如用户尚未完成身份验证。
  • ip_address:HTTP 请求的 IP 地址(如果存在)。
  • user_agent:HTTP 请求的 User-Agent 请求头(如果存在)。
  • triggered_by:事件的来源,可能的取值有:
  • user:事件来自面向终端用户的界面。
  • admin_api:事件来自 Admin API。
  • system:事件来自后台任务。
  • portal:事件来自不经过 Admin API 的管理台,例如「协作者已接受邀请」「域名已创建」。
  • preferred_languages:根据请求推断出的用户偏好语言。取值为 ui_locales 查询参数的值(如果提供),否则为 Accept-Language 请求头的值。当事件并非由终端用户产生时,该值为空数组。
  • language:根据用户偏好语言和应用的语言配置推导出的区域设置。默认值为应用的回退语言。
  • geo_location_code:根据 IP 地址推断出的位置的(ISO 3166-1 alpha-2 code)[https://www.iban.com/country-codes]。如果无法根据 IP 地址确定位置(例如该 IP 地址为内部地址),则为 null。
  • oauth:与 OAuth 相关的数据。如果事件不是来自 OAuth 流程(例如 SAML 登录),则该字段不存在。
  • state:授权请求的 state。
  • x_state:授权请求的 x_state。

阻塞事件(Blocking Events)

阻塞事件在操作执行之前触发,例如在创建用户之前。这让您可以通过程序中止或修改操作。

详细了解:

阻塞事件

非阻塞事件(Non-blocking Events)

非阻塞事件在操作执行之后触发,会在操作完成后异步投递给您的 Hook。

详细了解:

非阻塞事件

注册/登录流程中的事件触发点

本节说明每个事件在_默认_注册和登录流程中的触发时机,帮助您了解 Hook 可以在哪些环节与 Authany 交互。

请注意,在自定义身份验证流程中,事件的触发时机可能会有所变化。

图例:

  • 蓝色:阻塞事件
  • 绿色:非阻塞事件

默认注册流程

flowchart TD
    subgraph "Signup Flow"
        Start([Start])
        Start --> AuthenticationPreInitialize[authentication.pre_initialize]
        AuthenticationPreInitialize --> BotProtection[Bot Protection]
        BotProtection -- "Failed" --> BotProtectionVerificationFailed[bot_protection.verification.failed]
        BotProtection -- "Success" --> Identify[Identify]
        Identify --> AuthenticationPostIdentified[authentication.post_identified]
        AuthenticationPostIdentified --> Verify[Verify]
        Verify --> CreateAuthenticator[Create Authenticator]
        CreateAuthenticator --> AuthenticationPreAuthenticated[authentication.pre_authenticated]
        AuthenticationPreAuthenticated --> CreateAuthenticatorAdaptive["Create Authenticator<br>(Enforce AMR Constraints)"]
        CreateAuthenticatorAdaptive --> ViewRecoveryCode[View Recovery Code]
        ViewRecoveryCode --> PromptCreatePasskey[Prompt Create Passkey]
        PromptCreatePasskey --> UserPreCreate[user.pre_create]
        UserPreCreate --> CreateUser[Create User]
        CreateUser --> UserCreated[user.created]
        UserCreated --> FinishSignup([Finish])
    end

    subgraph "Authorization Code Exchange"
        ExchangeCode[Exchange Code for Tokens]
        ExchangeCode --> OIDCJWTPreCreate[oidc.jwt.pre_create]
        OIDCJWTPreCreate --> IssueTokens[Issue Tokens]
    end

    FinishSignup --> ExchangeCode

    classDef event fill:#98FB98,color:#000000
    classDef blockingEvent fill:#ADD8E6,color:#000000
    classDef processNode fill:#dddddd,color:#000000
    class BotProtectionVerificationFailed,UserCreated event
    class AuthenticationPreInitialize,AuthenticationPostIdentified,AuthenticationPreAuthenticated,UserPreCreate,OIDCJWTPreCreate blockingEvent
    class Start,BotProtection,Identify,Verify,CreateAuthenticator,ViewRecoveryCode,PromptCreatePasskey,CreateAuthenticatorAdaptive,CreateUser,FinishSignup,ExchangeCode,IssueTokens processNode

默认登录流程

flowchart TD
    subgraph "Login Flow"
        Start([Start])
        Start --> AuthenticationPreInitialize[authentication.pre_initialize]
        AuthenticationPreInitialize --> BotProtection[Bot Protection]
        BotProtection -- "Failed" --> BotProtectionVerificationFailed[bot_protection.verification.failed]
        BotProtection -- "Success" --> Identify[Identify]
        Identify -- "Success" --> AuthenticationPostIdentified[authentication.post_identified]
        Identify -- "Failed" --> AuthenticationIdentityLoginIDFailed[authentication.identity.login_id.failed]

        AuthenticationPostIdentified --> AuthenticatePrimary["Authenticate<br>(Primary Authenticator)"]

        AuthenticatePrimary -- "Success" --> AuthenticateSecondary["Authenticate<br>(Secondary Authenticator)"]
        AuthenticatePrimary -- "Failed" --> PrimaryAuthFailed["authentication.primary.password.failed<br>authentication.primary.oob_otp_email.failed<br>authentication.primary.oob_otp_sms.failed"]:::event

        AuthenticateSecondary -- "Success" --> AuthenticationPreAuthenticated[authentication.pre_authenticated]
        AuthenticateSecondary -- "Failed" --> SecondaryAuthFailed["authentication.secondary.password.failed<br>authentication.secondary.totp.failed<br>authentication.secondary.oob_otp_email.failed<br>authentication.secondary.oob_otp_sms.failed<br>authentication.secondary.recovery_code.failed"]:::event

        AuthenticationPreAuthenticated --> AuthenticateAdaptive["Authenticate<br>(Enforce AMR Constraints)"]
        AuthenticateAdaptive --> ChangePassword[Change Password]
        ChangePassword --> CheckAccountStatus[Check Account Status]
        CheckAccountStatus --> TerminateOtherSessions[Terminate Other Sessions]
        TerminateOtherSessions --> PromptCreatePasskey[Prompt Create Passkey]
        PromptCreatePasskey --> UserAuthenticated[user.authenticated]
        UserAuthenticated --> FinishLogin([Finish])
    end

    subgraph "Authorization Code Exchange"
        ExchangeCode[Exchange Code for Tokens]
        ExchangeCode --> OIDCJWTPreCreate[oidc.jwt.pre_create]
        OIDCJWTPreCreate --> IssueTokens[Issue Tokens]
    end

    FinishLogin --> ExchangeCode

    classDef event fill:#98FB98,color:#000000
    classDef blockingEvent fill:#ADD8E6,color:#000000
    classDef processNode fill:#dddddd,color:#000000
    class BotProtectionVerificationFailed,AuthenticationIdentityLoginIDFailed,PrimaryAuthFailed,SecondaryAuthFailed,UserAuthenticated event
    class AuthenticationPreInitialize,AuthenticationPostIdentified,AuthenticationPreAuthenticated,OIDCJWTPreCreate blockingEvent
    class Start,BotProtection,Identify,AuthenticatePrimary,AuthenticateSecondary,ChangePassword,CheckAccountStatus,TerminateOtherSessions,PromptCreatePasskey,AuthenticateAdaptive,ExchangeCode,IssueTokens,FinishLogin processNode