ory / kratos

The most scalable and customizable identity server on the market. Replace your Homegrown, Auth0, Okta, Firebase with better UX and DX. Has all the tablestakes: Passkeys, Social Sign In, Multi-Factor Auth, SMS, SAML, TOTP, and more. Written in Go, cloud native, headless, API-first. Available as a service on Ory Network and for self-hosters.
https://www.ory.sh/?utm_source=github&utm_medium=banner&utm_campaign=kratos
Apache License 2.0
11.34k stars 963 forks source link

Registration flow doesn't return to consent flow after verification via ajax api when using with kratos+hydra #4233

Open EverettSummer opened 1 day ago

EverettSummer commented 1 day ago

Preflight checklist

Ory Network Project

No response

Describe the bug

When using the Authorization Code Flow against Kratos + Hydra server, the user may not have an account with Kratos. In this scenario. The user will go through the registration flow of Kratos. After calling UpdateRegistrationFlow API in the UI, the Kratos returns a flow ID of verification flow and the UI navigates the user to verification. Then the user verified their email, but the response of UpdateVerificationFlow doesn't have a link to the consent page URL.

Reproducing the bug

  1. Register an oauth2 app with Authorization Code flow support.
  2. Start all containers
  3. start the oauth2 code flow.
  4. the app will redirect to the hydra oauth2 authorize endpoint.

    Request:

    GET http://127.0.0.1:4444/oauth2/auth?response_type=code&client_id=efd576ee-90bb-4363-9cd2-792bf9fb5a0c&state=NVQwd1RBeFBRQWZrX3hGNTVMR09BUzJ6ZTBsUUhxSUMzNGtuZ21Vdy5rV2p5&redirect_uri=http%3A%2F%2Flocalhost%3A4200&scope=openid%20offline_access%20offline%20email%20profile&code_challenge=bnA6z2C3KJInd4lgKIsPxcMCMnpaioZIGNx-KBjPhb0&code_challenge_method=S256&nonce=NVQwd1RBeFBRQWZrX3hGNTVMR09BUzJ6ZTBsUUhxSUMzNGtuZ21Vdy5rV2p5

Response:

{
    "Response Headers (2.385 kB)": {
        "headers": [
            {
                "name": "Cache-Control",
                "value": "private, no-cache, no-store, must-revalidate"
            },
            {
                "name": "Content-Length",
                "value": "1841"
            },
            {
                "name": "Content-Type",
                "value": "text/html; charset=utf-8"
            },
            {
                "name": "Date",
                "value": "Sun, 01 Dec 2024 05:15:56 GMT"
            },
            {
                "name": "Location",
                "value": "http://127.0.0.1:3000/login?login_challenge=61gTr3mbLnjo2NQVCxbKWFDoU8NWa7jetyXVrHYjptOoWfd-CJcUJYigkPGkACJDsA7q8Wl4wIti3FOCBxl4P9Fz3Sz866ZWHU2OX8AjddHGg-bRaGcccrMk2YjUqTqy4tP1k9d3IHjzdjOfexIcnBjIArpBoZrVJ74xHC4U-M-2gZabGow_otc_oTaqUYHRjRIds6kOEe4rVxlyW9E8eowVvKSNKfTRcJSkp1pdT6vGowJFMv5kFhiVbuUjWi8wn49ZT6SzIotcv5RZxMJ3nF-X5SmI4KQrqpJrUGc5bYb9CWQGQVqNj_u9638jzSxdasoTuQRZACIctVY7hCA4ICp2D39X9DDCG8f9gqSI2jiB8iIzM6qC6AM1uWvm8qqbwFEyEr17uG7TWB6im0sOPJmK347aNJTObN97TJBYThSGe2x3c9HUH-kAJfL6tgDtFu_ctHxbyIYchXZl-KEOhUHAxz4RQJ8QozTVymq6T-HpbvMraJWWUcIfO_ZlB8ohfU5Z5XlV-S89Vf6cdfoP9qz2ldbEz9-nEtg1wo0Iwb-Sa6y7Ud146xaMd_MSWhC1Srs7yTLgWhTUBfMih1F0Ce6O7mLIQb6kmaFl_RsunVC6wKWQb3vQqJepqP2sCBQAA04_1tp8XHWPSFzLcj5Va3RdzOqhOS_7F2-bPhSjhVM6eWDQ_Xa75EmnsU0bo3sCnnYonP43lsv_kC8sKKcdsXnfkqssIlf80uRSTOn3WE7EdK6_ENov-YeQF4XD99Y5quMGkm_QUuqzjbGFcucMXm2B2_DjqRN5vUuwSqNH6wMgcnaQBjXc7mTPkd9m0-NyBX2feCrHgBwb7C94uB3nJ6sj00EFEcPSZSXegHv2qio8jw10WDzRZR2OKaQS1Hs_CNQNfqW7Od6Pnyd8gIDS4J17-51kN7jzs4toXbVF5MB3NEMpBGZqdzYx3DFfbqJsZYsKmNluE2_llw8YNWXajWds0HP37mkBxIurjIMmJWZbtzk6q_dzQy7DuOX21PwoNA0dAqVlNlr-UZX85AHhBcgIe1HP7z2boI-4pAqU52qV36c__TLze7wZHD7S_VOccMI8vQ78lHu_9iJZyW2WItO2CgZqtjqGwZcSf9JakFlMqrq9ZpQtbqJ2kf2I1U4nXXJ0Lwl_uLx8L-MHPL8DS6WZkvKtc66wqwjngR-p-61l4lK8fNgE1HYucmPP1WYJFu2eXd8YP-R-wkoScuxEJmXQ4ZmodRj_eE-KPrsOxjduubIoMqqY1oW-yKM1ntVhiaMRjTv0Jv4xD7ve0D8TzofUsB2a4ym_DdUsKmqZRR18chGvLKDMhnwtGqLw9KNaytmd-LQ094eiumWuEXiYgUVwBVC3uoVaUC9vHAoA9MjT8fL9kPqzO0W2g3jjsWrf0CLs7xLzryGLZjLKnxG3ysZEqSPGk_x6YTDpP1dKZ9T4VlQolAb-aH_PrF8a8-8OVpm8N5X003D_7c3ZcmMFIC2rLNLsoBC3Bq0vevCoZadxkpGv5Lvz35fubyfrdLwWdxoXD6rWmHECToLbAWeFpkQTQZgVYsBRe1IHFpUaGrU2gvUL3MYx7loKltD0BFmC8qwKx9IjRpnUUkJBZcnJ4ycgEK2AcxLuDlT02WvC5IedgduZvPM_Pp_ZxUslK_bMQR6ID3eSjQOR73sLN2EQKQrEgLEVgCNv8LrKR04Asp-ukqAB6-1SGroJ5Qu8FTXRwHAi1w-AuZ6UaFFYdiz59aF81_5Tqr-fOWP2Z-wt1ai3-4_l"
            },
            {
                "name": "Set-Cookie",
                "value": "ory_hydra_login_csrf_dev_3759109255=MTczMzAzMDE1NnxqZmxhQk9pN1RaYk1qR3FxSjJnSHB2VE1qN3dyT1MydFJiazhwUkJCTW4xRWZaMkhxQ3pWSGFYbHNZb3BzUVlRaEMzUFJoWUUtNkFfaVRRTlkzdlViX1p0aFBSZTh6Wm44UTlJTURXZ0dVTGlJSFNnY0tfeV9xUXJiSXFnfPp0gRrXiiqMswLKa4fdfjEaFhcqAGgyb196pNh7BwfO; Path=/; Expires=Sun, 01 Dec 2024 05:45:56 GMT; Max-Age=1800; HttpOnly; SameSite=Lax"
            },
            {
                "name": "Vary",
                "value": "Origin"
            }
        ]
    }
}
  1. Then I start the registration flow, my frontend app start call the CreateBrowserRegistrationFlow endpoint.

    Request:

    GET http://127.0.0.1:4433/self-service/registration/browser?login_challenge=61gTr3mbLnjo2NQVCxbKWFDoU8NWa7jetyXVrHYjptOoWfd-CJcUJYigkPGkACJDsA7q8Wl4wIti3FOCBxl4P9Fz3Sz866ZWHU2OX8AjddHGg-bRaGcccrMk2YjUqTqy4tP1k9d3IHjzdjOfexIcnBjIArpBoZrVJ74xHC4U-M-2gZabGow_otc_oTaqUYHRjRIds6kOEe4rVxlyW9E8eowVvKSNKfTRcJSkp1pdT6vGowJFMv5kFhiVbuUjWi8wn49ZT6SzIotcv5RZxMJ3nF-X5SmI4KQrqpJrUGc5bYb9CWQGQVqNj_u9638jzSxdasoTuQRZACIctVY7hCA4ICp2D39X9DDCG8f9gqSI2jiB8iIzM6qC6AM1uWvm8qqbwFEyEr17uG7TWB6im0sOPJmK347aNJTObN97TJBYThSGe2x3c9HUH-kAJfL6tgDtFu_ctHxbyIYchXZl-KEOhUHAxz4RQJ8QozTVymq6T-HpbvMraJWWUcIfO_ZlB8ohfU5Z5XlV-S89Vf6cdfoP9qz2ldbEz9-nEtg1wo0Iwb-Sa6y7Ud146xaMd_MSWhC1Srs7yTLgWhTUBfMih1F0Ce6O7mLIQb6kmaFl_RsunVC6wKWQb3vQqJepqP2sCBQAA04_1tp8XHWPSFzLcj5Va3RdzOqhOS_7F2-bPhSjhVM6eWDQ_Xa75EmnsU0bo3sCnnYonP43lsv_kC8sKKcdsXnfkqssIlf80uRSTOn3WE7EdK6_ENov-YeQF4XD99Y5quMGkm_QUuqzjbGFcucMXm2B2_DjqRN5vUuwSqNH6wMgcnaQBjXc7mTPkd9m0-NyBX2feCrHgBwb7C94uB3nJ6sj00EFEcPSZSXegHv2qio8jw10WDzRZR2OKaQS1Hs_CNQNfqW7Od6Pnyd8gIDS4J17-51kN7jzs4toXbVF5MB3NEMpBGZqdzYx3DFfbqJsZYsKmNluE2_llw8YNWXajWds0HP37mkBxIurjIMmJWZbtzk6q_dzQy7DuOX21PwoNA0dAqVlNlr-UZX85AHhBcgIe1HP7z2boI-4pAqU52qV36c__TLze7wZHD7S_VOccMI8vQ78lHu_9iJZyW2WItO2CgZqtjqGwZcSf9JakFlMqrq9ZpQtbqJ2kf2I1U4nXXJ0Lwl_uLx8L-MHPL8DS6WZkvKtc66wqwjngR-p-61l4lK8fNgE1HYucmPP1WYJFu2eXd8YP-R-wkoScuxEJmXQ4ZmodRj_eE-KPrsOxjduubIoMqqY1oW-yKM1ntVhiaMRjTv0Jv4xD7ve0D8TzofUsB2a4ym_DdUsKmqZRR18chGvLKDMhnwtGqLw9KNaytmd-LQ094eiumWuEXiYgUVwBVC3uoVaUC9vHAoA9MjT8fL9kPqzO0W2g3jjsWrf0CLs7xLzryGLZjLKnxG3ysZEqSPGk_x6YTDpP1dKZ9T4VlQolAb-aH_PrF8a8-8OVpm8N5X003D_7c3ZcmMFIC2rLNLsoBC3Bq0vevCoZadxkpGv5Lvz35fubyfrdLwWdxoXD6rWmHECToLbAWeFpkQTQZgVYsBRe1IHFpUaGrU2gvUL3MYx7loKltD0BFmC8qwKx9IjRpnUUkJBZcnJ4ycgEK2AcxLuDlT02WvC5IedgduZvPM_Pp_ZxUslK_bMQR6ID3eSjQOR73sLN2EQKQrEgLEVgCNv8LrKR04Asp-ukqAB6-1SGroJ5Qu8FTXRwHAi1w-AuZ6UaFFYdiz59aF81_5Tqr-fOWP2Z-wt1ai3-4_l

Response:

{
    "id": "8256e608-5fd7-45f2-bca5-7aa790189e8b",
    "oauth2_login_challenge": "61gTr3mbLnjo2NQVCxbKWFDoU8NWa7jetyXVrHYjptOoWfd-CJcUJYigkPGkACJDsA7q8Wl4wIti3FOCBxl4P9Fz3Sz866ZWHU2OX8AjddHGg-bRaGcccrMk2YjUqTqy4tP1k9d3IHjzdjOfexIcnBjIArpBoZrVJ74xHC4U-M-2gZabGow_otc_oTaqUYHRjRIds6kOEe4rVxlyW9E8eowVvKSNKfTRcJSkp1pdT6vGowJFMv5kFhiVbuUjWi8wn49ZT6SzIotcv5RZxMJ3nF-X5SmI4KQrqpJrUGc5bYb9CWQGQVqNj_u9638jzSxdasoTuQRZACIctVY7hCA4ICp2D39X9DDCG8f9gqSI2jiB8iIzM6qC6AM1uWvm8qqbwFEyEr17uG7TWB6im0sOPJmK347aNJTObN97TJBYThSGe2x3c9HUH-kAJfL6tgDtFu_ctHxbyIYchXZl-KEOhUHAxz4RQJ8QozTVymq6T-HpbvMraJWWUcIfO_ZlB8ohfU5Z5XlV-S89Vf6cdfoP9qz2ldbEz9-nEtg1wo0Iwb-Sa6y7Ud146xaMd_MSWhC1Srs7yTLgWhTUBfMih1F0Ce6O7mLIQb6kmaFl_RsunVC6wKWQb3vQqJepqP2sCBQAA04_1tp8XHWPSFzLcj5Va3RdzOqhOS_7F2-bPhSjhVM6eWDQ_Xa75EmnsU0bo3sCnnYonP43lsv_kC8sKKcdsXnfkqssIlf80uRSTOn3WE7EdK6_ENov-YeQF4XD99Y5quMGkm_QUuqzjbGFcucMXm2B2_DjqRN5vUuwSqNH6wMgcnaQBjXc7mTPkd9m0-NyBX2feCrHgBwb7C94uB3nJ6sj00EFEcPSZSXegHv2qio8jw10WDzRZR2OKaQS1Hs_CNQNfqW7Od6Pnyd8gIDS4J17-51kN7jzs4toXbVF5MB3NEMpBGZqdzYx3DFfbqJsZYsKmNluE2_llw8YNWXajWds0HP37mkBxIurjIMmJWZbtzk6q_dzQy7DuOX21PwoNA0dAqVlNlr-UZX85AHhBcgIe1HP7z2boI-4pAqU52qV36c__TLze7wZHD7S_VOccMI8vQ78lHu_9iJZyW2WItO2CgZqtjqGwZcSf9JakFlMqrq9ZpQtbqJ2kf2I1U4nXXJ0Lwl_uLx8L-MHPL8DS6WZkvKtc66wqwjngR-p-61l4lK8fNgE1HYucmPP1WYJFu2eXd8YP-R-wkoScuxEJmXQ4ZmodRj_eE-KPrsOxjduubIoMqqY1oW-yKM1ntVhiaMRjTv0Jv4xD7ve0D8TzofUsB2a4ym_DdUsKmqZRR18chGvLKDMhnwtGqLw9KNaytmd-LQ094eiumWuEXiYgUVwBVC3uoVaUC9vHAoA9MjT8fL9kPqzO0W2g3jjsWrf0CLs7xLzryGLZjLKnxG3ysZEqSPGk_x6YTDpP1dKZ9T4VlQolAb-aH_PrF8a8-8OVpm8N5X003D_7c3ZcmMFIC2rLNLsoBC3Bq0vevCoZadxkpGv5Lvz35fubyfrdLwWdxoXD6rWmHECToLbAWeFpkQTQZgVYsBRe1IHFpUaGrU2gvUL3MYx7loKltD0BFmC8qwKx9IjRpnUUkJBZcnJ4ycgEK2AcxLuDlT02WvC5IedgduZvPM_Pp_ZxUslK_bMQR6ID3eSjQOR73sLN2EQKQrEgLEVgCNv8LrKR04Asp-ukqAB6-1SGroJ5Qu8FTXRwHAi1w-AuZ6UaFFYdiz59aF81_5Tqr-fOWP2Z-wt1ai3-4_l",
    "type": "browser",
    "expires_at": "2024-12-01T05:25:59.596317161Z",
    "issued_at": "2024-12-01T05:15:59.596317161Z",
    "request_url": "http://127.0.0.1:4433/self-service/registration/browser?login_challenge=61gTr3mbLnjo2NQVCxbKWFDoU8NWa7jetyXVrHYjptOoWfd-CJcUJYigkPGkACJDsA7q8Wl4wIti3FOCBxl4P9Fz3Sz866ZWHU2OX8AjddHGg-bRaGcccrMk2YjUqTqy4tP1k9d3IHjzdjOfexIcnBjIArpBoZrVJ74xHC4U-M-2gZabGow_otc_oTaqUYHRjRIds6kOEe4rVxlyW9E8eowVvKSNKfTRcJSkp1pdT6vGowJFMv5kFhiVbuUjWi8wn49ZT6SzIotcv5RZxMJ3nF-X5SmI4KQrqpJrUGc5bYb9CWQGQVqNj_u9638jzSxdasoTuQRZACIctVY7hCA4ICp2D39X9DDCG8f9gqSI2jiB8iIzM6qC6AM1uWvm8qqbwFEyEr17uG7TWB6im0sOPJmK347aNJTObN97TJBYThSGe2x3c9HUH-kAJfL6tgDtFu_ctHxbyIYchXZl-KEOhUHAxz4RQJ8QozTVymq6T-HpbvMraJWWUcIfO_ZlB8ohfU5Z5XlV-S89Vf6cdfoP9qz2ldbEz9-nEtg1wo0Iwb-Sa6y7Ud146xaMd_MSWhC1Srs7yTLgWhTUBfMih1F0Ce6O7mLIQb6kmaFl_RsunVC6wKWQb3vQqJepqP2sCBQAA04_1tp8XHWPSFzLcj5Va3RdzOqhOS_7F2-bPhSjhVM6eWDQ_Xa75EmnsU0bo3sCnnYonP43lsv_kC8sKKcdsXnfkqssIlf80uRSTOn3WE7EdK6_ENov-YeQF4XD99Y5quMGkm_QUuqzjbGFcucMXm2B2_DjqRN5vUuwSqNH6wMgcnaQBjXc7mTPkd9m0-NyBX2feCrHgBwb7C94uB3nJ6sj00EFEcPSZSXegHv2qio8jw10WDzRZR2OKaQS1Hs_CNQNfqW7Od6Pnyd8gIDS4J17-51kN7jzs4toXbVF5MB3NEMpBGZqdzYx3DFfbqJsZYsKmNluE2_llw8YNWXajWds0HP37mkBxIurjIMmJWZbtzk6q_dzQy7DuOX21PwoNA0dAqVlNlr-UZX85AHhBcgIe1HP7z2boI-4pAqU52qV36c__TLze7wZHD7S_VOccMI8vQ78lHu_9iJZyW2WItO2CgZqtjqGwZcSf9JakFlMqrq9ZpQtbqJ2kf2I1U4nXXJ0Lwl_uLx8L-MHPL8DS6WZkvKtc66wqwjngR-p-61l4lK8fNgE1HYucmPP1WYJFu2eXd8YP-R-wkoScuxEJmXQ4ZmodRj_eE-KPrsOxjduubIoMqqY1oW-yKM1ntVhiaMRjTv0Jv4xD7ve0D8TzofUsB2a4ym_DdUsKmqZRR18chGvLKDMhnwtGqLw9KNaytmd-LQ094eiumWuEXiYgUVwBVC3uoVaUC9vHAoA9MjT8fL9kPqzO0W2g3jjsWrf0CLs7xLzryGLZjLKnxG3ysZEqSPGk_x6YTDpP1dKZ9T4VlQolAb-aH_PrF8a8-8OVpm8N5X003D_7c3ZcmMFIC2rLNLsoBC3Bq0vevCoZadxkpGv5Lvz35fubyfrdLwWdxoXD6rWmHECToLbAWeFpkQTQZgVYsBRe1IHFpUaGrU2gvUL3MYx7loKltD0BFmC8qwKx9IjRpnUUkJBZcnJ4ycgEK2AcxLuDlT02WvC5IedgduZvPM_Pp_ZxUslK_bMQR6ID3eSjQOR73sLN2EQKQrEgLEVgCNv8LrKR04Asp-ukqAB6-1SGroJ5Qu8FTXRwHAi1w-AuZ6UaFFYdiz59aF81_5Tqr-fOWP2Z-wt1ai3-4_l",
    "ui": {
        "action": "http://127.0.0.1:4433/self-service/registration?flow=8256e608-5fd7-45f2-bca5-7aa790189e8b",
        "method": "POST",
        "nodes": [
            {
                "type": "input",
                "group": "default",
                "attributes": {
                    "name": "csrf_token",
                    "type": "hidden",
                    "value": "qkOqL3BOMqhfbxr4oOe0e9qGz9Gf8BLWV3H6hxj2gtetRM3ZMRtQ+yUm4Q3zJ3dUI7ezT4daxwFuiZITK1lPGg==",
                    "required": true,
                    "disabled": false,
                    "node_type": "input"
                },
                "messages": [],
                "meta": {}
            },
            {
                "type": "input",
                "group": "password",
                "attributes": {
                    "name": "traits.email",
                    "type": "email",
                    "required": true,
                    "autocomplete": "email",
                    "disabled": false,
                    "node_type": "input"
                },
                "messages": [],
                "meta": {
                    "label": {
                        "id": 1070002,
                        "text": "E-Mail",
                        "type": "info",
                        "context": {
                            "title": "E-Mail"
                        }
                    }
                }
            },
            {
                "type": "input",
                "group": "password",
                "attributes": {
                    "name": "password",
                    "type": "password",
                    "required": true,
                    "autocomplete": "new-password",
                    "disabled": false,
                    "node_type": "input"
                },
                "messages": [],
                "meta": {
                    "label": {
                        "id": 1070001,
                        "text": "Password",
                        "type": "info"
                    }
                }
            },
            {
                "type": "input",
                "group": "password",
                "attributes": {
                    "name": "traits.name",
                    "type": "text",
                    "required": true,
                    "disabled": false,
                    "node_type": "input"
                },
                "messages": [],
                "meta": {
                    "label": {
                        "id": 1070002,
                        "text": "Nickname",
                        "type": "info",
                        "context": {
                            "title": "Nickname"
                        }
                    }
                }
            },
            {
                "type": "input",
                "group": "password",
                "attributes": {
                    "name": "method",
                    "type": "submit",
                    "value": "password",
                    "disabled": false,
                    "node_type": "input"
                },
                "messages": [],
                "meta": {
                    "label": {
                        "id": 1040001,
                        "text": "Sign up",
                        "type": "info"
                    }
                }
            }
        ]
    },
    "organization_id": null,
    "state": "choose_method"
}
  1. I fill the form and submit via API UpdateRegistrationFlow:

    Request:

    POST http://127.0.0.1:4433/self-service/registration?flow=8256e608-5fd7-45f2-bca5-7aa790189e8b

    {
    "csrf_token": "qkOqL3BOMqhfbxr4oOe0e9qGz9Gf8BLWV3H6hxj2gtetRM3ZMRtQ+yUm4Q3zJ3dUI7ezT4daxwFuiZITK1lPGg==",
    "method": "password",
    "password": "Nvbct5zPUWZ;*SX",
    "traits.email": "test1@box.moe",
    "traits.name": "test1"
    }

Response:

{
    "session": {
        "id": "22a13057-b96f-4dbd-bfbc-14a759a13526",
        "active": true,
        "expires_at": "2024-12-02T05:16:26.261259599Z",
        "authenticated_at": "2024-12-01T05:16:26.261354779Z",
        "authenticator_assurance_level": "aal1",
        "authentication_methods": [
            {
                "method": "password",
                "aal": "aal1",
                "completed_at": "2024-12-01T05:16:26.261258549Z"
            }
        ],
        "issued_at": "2024-12-01T05:16:26.261259599Z",
        "identity": {
            "id": "d782fa58-b6f7-452c-81c3-82b80e9e4b45",
            "schema_id": "default",
            "schema_url": "http://127.0.0.1:4433/schemas/ZGVmYXVsdA",
            "state": "active",
            "state_changed_at": "2024-12-01T05:16:26.187878924Z",
            "traits": {
                "email": "test1@example.com",
                "name": "test1"
            },
            "verifiable_addresses": [
                {
                    "id": "2c05a38c-2eb0-4464-82aa-f900b8265fcb",
                    "value": "test1@example.com",
                    "verified": false,
                    "via": "email",
                    "status": "sent",
                    "created_at": "2024-12-01T05:16:26.207123Z",
                    "updated_at": "2024-12-01T05:16:26.207123Z"
                }
            ],
            "recovery_addresses": [
                {
                    "id": "1f8c7959-9cc8-4f02-b3ed-1ccd8539a5e1",
                    "value": "test1@example.com",
                    "via": "email",
                    "created_at": "2024-12-01T05:16:26.219246Z",
                    "updated_at": "2024-12-01T05:16:26.219246Z"
                }
            ],
            "metadata_public": null,
            "created_at": "2024-12-01T05:16:26.191444Z",
            "updated_at": "2024-12-01T05:16:26.191444Z",
            "organization_id": null
        },
        "devices": [
            {
                "id": "8b90406d-b83b-4814-9a81-c74d1c73550c",
                "ip_address": "172.18.0.1:50512",
                "user_agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:131.0) Gecko/20100101 Firefox/131.0",
                "location": ""
            }
        ]
    },
    "identity": {
        "id": "d782fa58-b6f7-452c-81c3-82b80e9e4b45",
        "schema_id": "default",
        "schema_url": "http://127.0.0.1:4433/schemas/ZGVmYXVsdA",
        "state": "active",
        "state_changed_at": "2024-12-01T05:16:26.187878924Z",
        "traits": {
            "email": "test1@example.com",
            "name": "test1"
        },
        "verifiable_addresses": [
            {
                "id": "2c05a38c-2eb0-4464-82aa-f900b8265fcb",
                "value": "test1@example.com",
                "verified": false,
                "via": "email",
                "status": "sent",
                "created_at": "2024-12-01T05:16:26.207123Z",
                "updated_at": "2024-12-01T05:16:26.207123Z"
            }
        ],
        "recovery_addresses": [
            {
                "id": "1f8c7959-9cc8-4f02-b3ed-1ccd8539a5e1",
                "value": "test1@example.com",
                "via": "email",
                "created_at": "2024-12-01T05:16:26.219246Z",
                "updated_at": "2024-12-01T05:16:26.219246Z"
            }
        ],
        "metadata_public": null,
        "created_at": "2024-12-01T05:16:26.191444Z",
        "updated_at": "2024-12-01T05:16:26.191444Z",
        "organization_id": null
    },
    "continue_with": [
        {
            "action": "redirect_browser_to",
            "redirect_browser_to": "http://127.0.0.1:3000/"
        },
        {
            "action": "show_verification_ui",
            "flow": {
                "id": "cc4376f1-9dd3-4926-9966-47e0b0fe0b2a",
                "verifiable_address": "test1@example.com",
                "url": "http://127.0.0.1:3000/verification?flow=cc4376f1-9dd3-4926-9966-47e0b0fe0b2a"
            }
        }
    ]
}
  1. My frontend follows the continue_with array and redirects to verification page.

    Request:

    GET http://box.moe:4433/self-service/verification/flows?id=cc4376f1-9dd3-4926-9966-47e0b0fe0b2a

    Response:

    {
    "id": "cc4376f1-9dd3-4926-9966-47e0b0fe0b2a",
    "type": "browser",
    "expires_at": "2024-12-01T06:16:26.292948Z",
    "issued_at": "2024-12-01T05:16:26.292948Z",
    "request_url": "http://127.0.0.1:4433/self-service/registration/browser?login_challenge=61gTr3mbLnjo2NQVCxbKWFDoU8NWa7jetyXVrHYjptOoWfd-CJcUJYigkPGkACJDsA7q8Wl4wIti3FOCBxl4P9Fz3Sz866ZWHU2OX8AjddHGg-bRaGcccrMk2YjUqTqy4tP1k9d3IHjzdjOfexIcnBjIArpBoZrVJ74xHC4U-M-2gZabGow_otc_oTaqUYHRjRIds6kOEe4rVxlyW9E8eowVvKSNKfTRcJSkp1pdT6vGowJFMv5kFhiVbuUjWi8wn49ZT6SzIotcv5RZxMJ3nF-X5SmI4KQrqpJrUGc5bYb9CWQGQVqNj_u9638jzSxdasoTuQRZACIctVY7hCA4ICp2D39X9DDCG8f9gqSI2jiB8iIzM6qC6AM1uWvm8qqbwFEyEr17uG7TWB6im0sOPJmK347aNJTObN97TJBYThSGe2x3c9HUH-kAJfL6tgDtFu_ctHxbyIYchXZl-KEOhUHAxz4RQJ8QozTVymq6T-HpbvMraJWWUcIfO_ZlB8ohfU5Z5XlV-S89Vf6cdfoP9qz2ldbEz9-nEtg1wo0Iwb-Sa6y7Ud146xaMd_MSWhC1Srs7yTLgWhTUBfMih1F0Ce6O7mLIQb6kmaFl_RsunVC6wKWQb3vQqJepqP2sCBQAA04_1tp8XHWPSFzLcj5Va3RdzOqhOS_7F2-bPhSjhVM6eWDQ_Xa75EmnsU0bo3sCnnYonP43lsv_kC8sKKcdsXnfkqssIlf80uRSTOn3WE7EdK6_ENov-YeQF4XD99Y5quMGkm_QUuqzjbGFcucMXm2B2_DjqRN5vUuwSqNH6wMgcnaQBjXc7mTPkd9m0-NyBX2feCrHgBwb7C94uB3nJ6sj00EFEcPSZSXegHv2qio8jw10WDzRZR2OKaQS1Hs_CNQNfqW7Od6Pnyd8gIDS4J17-51kN7jzs4toXbVF5MB3NEMpBGZqdzYx3DFfbqJsZYsKmNluE2_llw8YNWXajWds0HP37mkBxIurjIMmJWZbtzk6q_dzQy7DuOX21PwoNA0dAqVlNlr-UZX85AHhBcgIe1HP7z2boI-4pAqU52qV36c__TLze7wZHD7S_VOccMI8vQ78lHu_9iJZyW2WItO2CgZqtjqGwZcSf9JakFlMqrq9ZpQtbqJ2kf2I1U4nXXJ0Lwl_uLx8L-MHPL8DS6WZkvKtc66wqwjngR-p-61l4lK8fNgE1HYucmPP1WYJFu2eXd8YP-R-wkoScuxEJmXQ4ZmodRj_eE-KPrsOxjduubIoMqqY1oW-yKM1ntVhiaMRjTv0Jv4xD7ve0D8TzofUsB2a4ym_DdUsKmqZRR18chGvLKDMhnwtGqLw9KNaytmd-LQ094eiumWuEXiYgUVwBVC3uoVaUC9vHAoA9MjT8fL9kPqzO0W2g3jjsWrf0CLs7xLzryGLZjLKnxG3ysZEqSPGk_x6YTDpP1dKZ9T4VlQolAb-aH_PrF8a8-8OVpm8N5X003D_7c3ZcmMFIC2rLNLsoBC3Bq0vevCoZadxkpGv5Lvz35fubyfrdLwWdxoXD6rWmHECToLbAWeFpkQTQZgVYsBRe1IHFpUaGrU2gvUL3MYx7loKltD0BFmC8qwKx9IjRpnUUkJBZcnJ4ycgEK2AcxLuDlT02WvC5IedgduZvPM_Pp_ZxUslK_bMQR6ID3eSjQOR73sLN2EQKQrEgLEVgCNv8LrKR04Asp-ukqAB6-1SGroJ5Qu8FTXRwHAi1w-AuZ6UaFFYdiz59aF81_5Tqr-fOWP2Z-wt1ai3-4_l",
    "active": "code",
    "ui": {
        "action": "http://127.0.0.1:4433/self-service/verification?flow=cc4376f1-9dd3-4926-9966-47e0b0fe0b2a",
        "method": "POST",
        "nodes": [
            {
                "type": "input",
                "group": "code",
                "attributes": {
                    "name": "method",
                    "type": "hidden",
                    "value": "code",
                    "disabled": false,
                    "node_type": "input"
                },
                "messages": [],
                "meta": {}
            },
            {
                "type": "input",
                "group": "code",
                "attributes": {
                    "name": "code",
                    "type": "text",
                    "required": true,
                    "disabled": false,
                    "node_type": "input"
                },
                "messages": [],
                "meta": {
                    "label": {
                        "id": 1070011,
                        "text": "Verification code",
                        "type": "info"
                    }
                }
            },
            {
                "type": "input",
                "group": "code",
                "attributes": {
                    "name": "method",
                    "type": "submit",
                    "value": "code",
                    "disabled": false,
                    "node_type": "input"
                },
                "messages": [],
                "meta": {
                    "label": {
                        "id": 1070009,
                        "text": "Continue",
                        "type": "info"
                    }
                }
            },
            {
                "type": "input",
                "group": "default",
                "attributes": {
                    "name": "csrf_token",
                    "type": "hidden",
                    "value": "pRvb3wjfOdI5T6WKkwJcSF4xJ6RhFvwZD3m258/rIbtv35aGa085rOIV4NHxsKKUTNYuLZXTNeLL6sYKDMujhg==",
                    "required": true,
                    "disabled": false,
                    "node_type": "input"
                },
                "messages": [],
                "meta": {}
            }
        ],
        "messages": [
            {
                "id": 1080003,
                "text": "An email containing a verification code has been sent to the email address you provided. If you have not received an email, check the spelling of the address and make sure to use the address you registered with.",
                "type": "info"
            }
        ]
    },
    "state": "sent_email"
    }
  2. I find the code from mailspur and call UpdateVerificationFlow

    Request:

    POST http://127.0.0.1:4433/self-service/verification?flow=cc4376f1-9dd3-4926-9966-47e0b0fe0b2a

    Request Body

    {
    "code": "189010",
    "csrf_token": "pRvb3wjfOdI5T6WKkwJcSF4xJ6RhFvwZD3m258/rIbtv35aGa085rOIV4NHxsKKUTNYuLZXTNeLL6sYKDMujhg==",
    "method": "code"
    }

Response:

{
    "id": "cc4376f1-9dd3-4926-9966-47e0b0fe0b2a",
    "type": "browser",
    "expires_at": "2024-12-01T06:16:26.292948Z",
    "issued_at": "2024-12-01T05:16:26.292948Z",
    "request_url": "http://127.0.0.1:4433/self-service/registration/browser?login_challenge=61gTr3mbLnjo2NQVCxbKWFDoU8NWa7jetyXVrHYjptOoWfd-CJcUJYigkPGkACJDsA7q8Wl4wIti3FOCBxl4P9Fz3Sz866ZWHU2OX8AjddHGg-bRaGcccrMk2YjUqTqy4tP1k9d3IHjzdjOfexIcnBjIArpBoZrVJ74xHC4U-M-2gZabGow_otc_oTaqUYHRjRIds6kOEe4rVxlyW9E8eowVvKSNKfTRcJSkp1pdT6vGowJFMv5kFhiVbuUjWi8wn49ZT6SzIotcv5RZxMJ3nF-X5SmI4KQrqpJrUGc5bYb9CWQGQVqNj_u9638jzSxdasoTuQRZACIctVY7hCA4ICp2D39X9DDCG8f9gqSI2jiB8iIzM6qC6AM1uWvm8qqbwFEyEr17uG7TWB6im0sOPJmK347aNJTObN97TJBYThSGe2x3c9HUH-kAJfL6tgDtFu_ctHxbyIYchXZl-KEOhUHAxz4RQJ8QozTVymq6T-HpbvMraJWWUcIfO_ZlB8ohfU5Z5XlV-S89Vf6cdfoP9qz2ldbEz9-nEtg1wo0Iwb-Sa6y7Ud146xaMd_MSWhC1Srs7yTLgWhTUBfMih1F0Ce6O7mLIQb6kmaFl_RsunVC6wKWQb3vQqJepqP2sCBQAA04_1tp8XHWPSFzLcj5Va3RdzOqhOS_7F2-bPhSjhVM6eWDQ_Xa75EmnsU0bo3sCnnYonP43lsv_kC8sKKcdsXnfkqssIlf80uRSTOn3WE7EdK6_ENov-YeQF4XD99Y5quMGkm_QUuqzjbGFcucMXm2B2_DjqRN5vUuwSqNH6wMgcnaQBjXc7mTPkd9m0-NyBX2feCrHgBwb7C94uB3nJ6sj00EFEcPSZSXegHv2qio8jw10WDzRZR2OKaQS1Hs_CNQNfqW7Od6Pnyd8gIDS4J17-51kN7jzs4toXbVF5MB3NEMpBGZqdzYx3DFfbqJsZYsKmNluE2_llw8YNWXajWds0HP37mkBxIurjIMmJWZbtzk6q_dzQy7DuOX21PwoNA0dAqVlNlr-UZX85AHhBcgIe1HP7z2boI-4pAqU52qV36c__TLze7wZHD7S_VOccMI8vQ78lHu_9iJZyW2WItO2CgZqtjqGwZcSf9JakFlMqrq9ZpQtbqJ2kf2I1U4nXXJ0Lwl_uLx8L-MHPL8DS6WZkvKtc66wqwjngR-p-61l4lK8fNgE1HYucmPP1WYJFu2eXd8YP-R-wkoScuxEJmXQ4ZmodRj_eE-KPrsOxjduubIoMqqY1oW-yKM1ntVhiaMRjTv0Jv4xD7ve0D8TzofUsB2a4ym_DdUsKmqZRR18chGvLKDMhnwtGqLw9KNaytmd-LQ094eiumWuEXiYgUVwBVC3uoVaUC9vHAoA9MjT8fL9kPqzO0W2g3jjsWrf0CLs7xLzryGLZjLKnxG3ysZEqSPGk_x6YTDpP1dKZ9T4VlQolAb-aH_PrF8a8-8OVpm8N5X003D_7c3ZcmMFIC2rLNLsoBC3Bq0vevCoZadxkpGv5Lvz35fubyfrdLwWdxoXD6rWmHECToLbAWeFpkQTQZgVYsBRe1IHFpUaGrU2gvUL3MYx7loKltD0BFmC8qwKx9IjRpnUUkJBZcnJ4ycgEK2AcxLuDlT02WvC5IedgduZvPM_Pp_ZxUslK_bMQR6ID3eSjQOR73sLN2EQKQrEgLEVgCNv8LrKR04Asp-ukqAB6-1SGroJ5Qu8FTXRwHAi1w-AuZ6UaFFYdiz59aF81_5Tqr-fOWP2Z-wt1ai3-4_l",
    "active": "code",
    "ui": {
        "action": "http://127.0.0.1:3000/",
        "method": "GET",
        "nodes": [
            {
                "type": "input",
                "group": "default",
                "attributes": {
                    "name": "csrf_token",
                    "type": "hidden",
                    "value": "GgbGHaTIgeNnMmMYBGp2fBoC8mknhpO1Xtf2Ddhv1fnQwotEx1iBnbxoJkNm2IigCOX74NNDWk6aRIbgG09XxA==",
                    "required": true,
                    "disabled": false,
                    "node_type": "input"
                },
                "messages": [],
                "meta": {}
            },
            {
                "type": "a",
                "group": "code",
                "attributes": {
                    "href": "http://127.0.0.1:3000/",
                    "title": {
                        "id": 1070009,
                        "text": "Continue",
                        "type": "info"
                    },
                    "id": "continue",
                    "node_type": "a"
                },
                "messages": [],
                "meta": {
                    "label": {
                        "id": 1070009,
                        "text": "Continue",
                        "type": "info"
                    }
                }
            }
        ],
        "messages": [
            {
                "id": 1080002,
                "text": "You successfully verified your email address.",
                "type": "success"
            }
        ]
    },
    "state": "passed_challenge"
}

The issue is the final response doesn't contain links to consent page.

Relevant log output

## Kratos Logs:
https://gist.github.com/EverettSummer/79965016b2f1ec22b0e7377425ae21a8

## Hydra Logs:

https://gist.github.com/EverettSummer/0ba1f8164a79441ba03ab3bc366d70d3

Relevant configuration

# docker-compose.yml

version: '3.9'
services:
  postgresd:
    image: postgres:15
    environment:
      - POSTGRES_USER=kratos
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=kratos
    ports:
      - '${EXPOSED_POSTGRES_PORT:-5432}:5432'
    volumes:
      - ${POSTGRES_DATA:-./pg_data}:/var/lib/postgresql/data
    networks:
      - ory-network
  kratos-migrate:
    image: oryd/kratos:v1.3.1
    environment:
      - DSN=postgres://kratos:secret@postgresd:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4
    volumes:
      - type: bind
        source: ./kratos
        target: /etc/config/kratos
    command: -c /etc/config/kratos/kratos.yml migrate sql -e --yes
    restart: "no"
    networks:
      - ory-network
  kratos:
    depends_on:
      - kratos-migrate
    image: oryd/kratos:v1.3.1
    ports:
      - '4433:4433' # public
      - '4434:4434' # admin
    restart: "no"
    environment:
      - DSN=postgres://kratos:secret@postgresd:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4
      - LOG_LEVEL=trace
    command: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier
    stdin_open: true
    tty: true
    volumes:
      - type: bind
        source: ./kratos
        target: /etc/config/kratos
    networks:
      - ory-network
  mailslurper:
    image: oryd/mailslurper:latest-smtps
    ports:
      - '4436:4436'
      - '4437:4437'
    networks:
      - ory-network
  oathkeeper:
    image: oryd/oathkeeper:latest
    ports:
      - 8080:4455
      - 4456:4456
    command: serve proxy -c "/etc/config/oathkeeper/oathkeeper.yml"
    environment:
      - LOG_LEVEL=debug
    volumes:
      - ./oathkeeper:/etc/config/oathkeeper
    restart: "no"
    networks:
      - ory-network
  hydra-migrate:
    image: oryd/hydra:v2.2.0
    environment:
      - DSN=postgres://kratos:secret@postgresd:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4
    volumes:
      - ./hydra:/etc/config/hydra
    command: migrate -c /etc/config/hydra/hydra.yml sql -e --yes
    restart: "no"
    networks:
      - ory-network
  hydra:
    image: oryd/hydra:v2.2.0
    depends_on:
      - hydra-migrate
    ports:
      - "4444:4444" # Public port
      - "4445:4445" # Admin port
      - "5555:5555" # Port for hydra token user
    command:
      # serve all --dangerous-force-http
      serve -c /etc/config/hydra/hydra.yml all --dev
    restart: "no"
    environment:
      - DSN=postgres://kratos:secret@postgresd:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4
    volumes:
      - ./hydra:/etc/config/hydra
    networks:
      - ory-network
#  nginx:
#    image: nginx:1.25
#    ports:
#      - '3000:3000'
#      - '3100:3100'
#    volumes:
#      - ${NGINX_CONFIG:-./nginx/nginx.conf}:/etc/nginx/nginx.conf:ro
##      - ${HTTPS_CERT:-./nginx/box-moe-cert.pem}:/etc/nginx/box-moe-cert.pem:ro
##      - ${HTTPS_KEY:-./nginx/box-moe-key.pem}:/etc/nginx/box-moe-key.pem:ro
#      - ${NGINX_STATIC_ADMIN:-./admin-static}:/home/nginx/admin
#      - ${NGINX_STATIC_MIRA_IDENTITY:-../dist/mira-identity-provider}:/home/nginx/mira
#    restart: "no"
#    networks:
#      - ory-network
networks:
  ory-network:
    name: ory_default
    external: true

# Kratos.yml
version: v1.3.0

dsn: memory

serve:
  public:
    base_url: http://127.0.0.1:4433/
    cors:
      allowed_origins:
        - http://127.0.0.1:3000
        - http://127.0.0.1:5000
        - http://127.0.0.1:3300
      exposed_headers:
        - 'Content-Type'
        - 'Set-Cookie'
      enabled: true
      debug: true
  admin:
    base_url: http://127.0.0.1:4434/

selfservice:
  default_browser_return_url: http://127.0.0.1:3000/
  allowed_return_urls:
    - http://127.0.0.1:3000
    - http://127.0.0.1:4444
  methods:
    password:
      enabled: true
    code:
      enabled: true

  flows:
    error:
      ui_url: http://127.0.0.1:3000/error

    settings:
      ui_url: http://127.0.0.1:3000/settings/account
      privileged_session_max_age: 15m
      required_aal: highest_available

    recovery:
      enabled: true
      ui_url: http://127.0.0.1:3000/recovery
      use: code

    verification:
      enabled: true
      ui_url: http://127.0.0.1:3000/verification
      use: code
#      after:
#        hooks:
#          - hook: session
#        default_browser_return_url: http://127.0.0.1:3000/

    logout:
      after:
        default_browser_return_url: http://127.0.0.1:3000/login

    login:
      ui_url: http://127.0.0.1:3000/login
      lifespan: 10m
      after:
        password:
          hooks:
            - hook: require_verified_address

    registration:
      lifespan: 10m
      ui_url: http://127.0.0.1:3000/registration
      enable_legacy_one_step: true
      after:
        password:
          hooks:
            - hook: session
            - hook: show_verification_ui

database:
  cleanup:
    batch_size: 10
    sleep:
      tables: 1m
    older_than: 0s

log:
  level: trace
  format: json
  leak_sensitive_values: true

secrets:
  cookie:
    - PLEASE-CHANGE-ME-I-AM-VERY-INSECURE
  cipher:
    - 32-LONG-SECRET-NOT-SECURE-AT-ALL

ciphers:
  algorithm: xchacha20-poly1305

hashers:
  algorithm: bcrypt
  bcrypt:
    cost: 8

identity:
  default_schema_id: default
  schemas:
    - id: default
      url: file:///etc/config/kratos/identity.schema.json

courier:
  smtp:
    connection_uri: smtps://test:test@mailslurper:1025/?skip_ssl_verify=true

cookies:
  same_site: Lax

# OAuth 2.0 Provider URL.
# If set, the login and registration flows will handle the Ory OAuth 2.0 & OpenID `login_challenge` query parameter to
#  serve as an OpenID Connect Provider. This URL should point to Ory Hydra when you are not running on the Ory Network
#  and be left untouched otherwise.
oauth2_provider:
  url: http://hydra:4445
#  headers:
#    Authorization: Bearer some-token
  override_return_to: true

# hydra.yml

log:
  leak_sensitive_values: true
serve:
  public:
    cors:
      enabled: true
      allowed_origins:
        - http://localhost:4200
#        - http://127.0.0.1:3000
      allowed_methods:
        - POST
        - GET
        - PUT
        - PATCH
        - DELETE
      allowed_headers:
        - "Authorization"
      exposed_headers:
        - "Content-Type"
      allow_credentials: true
      max_age: 0
      debug: false
  admin:
    cors:
      enabled: false
      allowed_origins:
        - http://127.0.0.1:3000
      allow_credentials: true
  cookies:
    same_site_mode: Lax
urls:
  self:
    issuer: http://127.0.0.1:4444
    public: http://127.0.0.1:4444
    admin: http://127.0.0.1:4445
  consent: http://127.0.0.1:3000/consent
  login: http://127.0.0.1:3000/login
  logout: http://127.0.0.1:3000/logout
  identity_provider:
    url: http://kratos:4434/
    publicUrl: http://kratos:4433/

secrets:
  system:
    - ProjectMiraDevSecretDoNotUseInProd

strategies:
  access_token: jwt

oidc:
  subject_identifiers:
    supported_types:
      - pairwise
      - public
    pairwise:
      salt: youReallyNeedToChangeThis

webfinger:
  oidc_discovery:
    supported_claims:
      - email
      - profile
    supported_scope:
      - email
      - profile

oauth2:
  expose_internal_errors: true

# identity.schema.json
{
  "$id": "https://schemas.ory.sh/presets/kratos/email-password/identity.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Person",
  "type": "object",
  "properties": {
    "traits": {
      "type": "object",
      "properties": {
        "email": {
          "type": "string",
          "format": "email",
          "title": "E-Mail",
          "minLength": 3,
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            },
            "verification": {
              "via": "email"
            },
            "recovery": {
              "via": "email"
            }
          }
        },
        "name": {
          "type": "string",
          "title": "Nickname"
        }
      },
      "required": [
        "email",
        "name"
      ],
      "additionalProperties": false
    }
  }
}

Version

1.3.1

On which operating system are you observing this issue?

None

In which environment are you deploying?

None

Additional Context

Hydra version is 2.2.0

EverettSummer commented 1 day ago

Currently, I use this workaround. get the return_to from the response of the API CreateLoginFlowForBrowser. and append it to the url of the registration page, then pass the return_to to the after_verification_return_to parameter. so that I can return to the OAuth2 flow after verified email. But this is a little inconvenient. Hydra will redirect to the login page again, and we cannot set the login flow to skip the password re-verification when the user has already logon.