square-napkin-92357
06/09/2025, 10:15 AMbrief-egg-61061
06/09/2025, 10:15 AMbrief-egg-61061
06/09/2025, 10:15 AMhydra create client
or hydra create oauth2-client
command. Here’s a typical example: bash hydra create oauth2-client \ --name "my app" \ --redirect-uri <http://localhost/cb> \ --grant-type authorization_code \ --response-type code \ --scope openid,offline_access \ --token-endpoint-auth-method client_secret_post
This will output the client ID and secret. You can also use --format json
to get a JSON response, which you can parse with tools like `jq`: bash client=$(hydra create oauth2-client --format json ...) client_id=$(echo $client | jq -r '.client_id') client_secret=$(echo $client | jq -r '.client_secret')
[hydra create oauth2-client](https://www.ory.sh/docs/hydra/cli/hydra-create-oauth2-client#hydra-create-oauth2-client) --- ### 2. Using the REST API You can create a client by sending a POST request to the /admin/clients
endpoint. For example: bash curl -X POST '<http://localhost:4445/admin/clients>' \ -H 'Content-Type: application/json' \ -d '{ "client_name": "my app", "grant_types": ["authorization_code"], "redirect_uris": ["<http://localhost/cb>"], "response_types": ["code"], "scope": "openid offline_access", "token_endpoint_auth_method": "client_secret_post" }'
[Hydra API Reference](https://www.ory.sh/docs/hydra/reference/api) --- ### 3. Using the Go SDK You can also use the Ory Hydra Go SDK to create a client programmatically: go package main import ( "context" "fmt" "os" client "<http://github.com/ory/hydra-client-go|github.com/ory/hydra-client-go>" ) func main() { oAuth2Client := *client.NewOAuth2Client() oAuth2Client.SetClientName("example_client") oAuth2Client.SetRedirectUris([]string{"<http://localhost/cb>"}) oAuth2Client.SetGrantTypes([]string{"authorization_code"}) oAuth2Client.SetResponseTypes([]string{"code"}) oAuth2Client.SetScope("openid offline_access") configuration := client.NewConfiguration() configuration.Servers = []client.ServerConfiguration{ {URL: "<http://localhost:4445>"}, } apiClient := client.NewAPIClient(configuration) resp, _, err := apiClient.OAuth2Api.CreateOAuth2Client(context.Background()).OAuth2Client(oAuth2Client).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) return } fmt.Printf("Created client with name %s\n", resp.GetClientName()) }
[Ory Hydra Go SDK](https://www.ory.sh/docs/hydra/self-hosted/go) --- Choose the method that best fits your workflow. If you need more details or a specific example, let me know!square-napkin-92357
06/09/2025, 10:17 AM{
"client_id": "f1be3f86-d419-461a-a5ac-04eaed0019b1",
"client_name": "my app",
"client_secret": "gJe0wMjt6svipvcQ5_iuA8v_88",
"redirect_uris": [
"<http://localhost/cb>"
],
"grant_types": [
"authorization_code"
],
"response_types": [
"code"
],
"scope": "openid offline_access",
"audience": [],
"owner": "",
"policy_uri": "",
"allowed_cors_origins": [],
"tos_uri": "",
"client_uri": "",
"logo_uri": "",
"contacts": null,
"client_secret_expires_at": 0,
"subject_type": "public",
"jwks": {},
"token_endpoint_auth_method": "client_secret_post",
"userinfo_signed_response_alg": "none",
"created_at": "2025-06-09T10:16:16Z",
"updated_at": "2025-06-09T10:16:16.480334Z",
"metadata": {},
"registration_access_token": "ory_at_m2KkGufii6sQ18mhgVu3cDBwzfPaUgCmP3UWKtmHupc.5Oiyh8APlDxncqhh2lUawCJYwd_D76rtgD2EAhVTwto",
"registration_client_uri": "<http://127.0.0.1:4444/oauth2/register/>",
"skip_consent": false,
"skip_logout_consent": null,
"authorization_code_grant_access_token_lifespan": null,
"authorization_code_grant_id_token_lifespan": null,
"authorization_code_grant_refresh_token_lifespan": null,
"client_credentials_grant_access_token_lifespan": null,
"implicit_grant_access_token_lifespan": null,
"implicit_grant_id_token_lifespan": null,
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
}
how about the next step?brief-egg-61061
06/09/2025, 10:17 AMbrief-egg-61061
06/09/2025, 10:17 AMbash ory perform authorization-code \ --client-id "f1be3f86-d419-461a-a5ac-04eaed0019b1" \ --client-secret "gJe0wMjt6svipvcQ5_iuA8v_88" \ --project <your-project-id> \ --port 5555 \ --scope openid,offline_access
This command will open a browser window at <http://127.0.0.1:5555/>
(or you can navigate there manually). You will be prompted to log in and consent to the requested scopes. After successful authentication and consent, you will receive the tokens (access token, refresh token, and ID token if the scopes were requested) [Try common OAuth2 Grants](https://www.ory.sh/docs/getting-started/ory-network-oauth2#authorization-code-grant) [Try out custom OAuth2 login and consent](https://www.ory.sh/docs/hydra/guides/custom-ui-oauth2#run-the-flow). --- ### 2. What Happens Next - Login: Enter user credentials on the login screen. - Consent: Approve the requested scopes. - Tokens: After consent, you’ll see the tokens issued to your client. You can inspect the access token using the Ory CLI: bash ory introspect token <access_token> --project <your-project-id>
--- If you are running Ory Hydra locally, you can use the hydra perform authorization-code
command in a similar way, or follow the browser-based flow as described above [Ory Hydra OAuth2 Server Quickstart](https://www.ory.sh/docs/hydra/self-hosted/quickstart). --- If you need to implement this in your own application, you would redirect the user to the authorization endpoint, handle the callback, and exchange the authorization code for tokens as shown in the documentation [OAuth2 authorization code flow](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow). Let me know if you need a code example for a specific language or framework!square-napkin-92357
06/09/2025, 10:21 AMbrief-egg-61061
06/09/2025, 10:21 AMbrief-egg-61061
06/09/2025, 10:21 AMhttp://<hydra-public-url>/oauth2/auth?response_type=code &client_id=<your_client_id> &redirect_uri=<your_redirect_uri> &scope=openid%20offline_access &state=<random_state>
- The user will be prompted to log in and consent to the requested scopes [OAuth2 authorization code flow](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow). --- ### 2. User Grants Consent - After login and consent, the user is redirected back to your redirect_uri
with a code
and state
parameter. --- ### 3. Exchange the Authorization Code for an Access Token Make a POST request to the token endpoint: bash curl -X POST 'http://<hydra-public-url>/oauth2/token' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=authorization_code' \ -d 'code=<code_from_query_param>' \ -d 'redirect_uri=<your_redirect_uri>' \ -d 'client_id=<your_client_id>' \ -d 'client_secret=<your_client_secret>'
- If successful, the response will include an access_token
, and if you requested the offline_access
scope, a refresh_token
as well [OAuth2 authorization code flow](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow#web-server-app-and-confidential-client). --- ### Example Flow 1. User visits: <http://localhost:4444/oauth2/auth?response_type=code&client_id=f1be3f86-d419-461a-a5ac-04eaed0019b1&redirect_uri=http://localhost/cb&scope=openid%20offline_access&state=xyz>
2. User logs in and consents. 3. User is redirected to: <http://localhost/cb?code=AUTH_CODE&state=xyz>
4. Your app exchanges the code for tokens as shown above. --- For a hands-on example, you can also use the Ory CLI to perform the flow and see the tokens in your terminal [Try common OAuth2 Grants](https://www.ory.sh/docs/getting-started/ory-network-oauth2#authorization-code-grant). If you need a code sample for a specific language or more details, let me know!square-napkin-92357
06/09/2025, 10:46 AMbrief-egg-61061
06/09/2025, 10:46 AMbrief-egg-61061
06/09/2025, 10:46 AMbash curl -X POST '<http://localhost:4445/admin/clients>' \ -H 'Content-Type: application/json' \ -d '{ "client_name": "my app", "grant_types": ["authorization_code"], "redirect_uris": ["<http://localhost/cb>"], "response_types": ["code"], "scope": "openid offline_access", "token_endpoint_auth_method": "client_secret_post" }'
This will return a JSON object with client_id
and client_secret
you’ll use in the next steps. --- ## 2. Redirect User to the Authorization Endpoint Construct a URL and redirect the user to it: <http://localhost:4444/oauth2/auth?response_type=code> &client_id=<client_id> &redirect_uri=<http://localhost/cb> &scope=openid%20offline_access &state=xyz
The user will log in and consent. After that, they’ll be redirected to your redirect_uri
with a code
and state
parameter [Ory Hydra OAuth2 Server Quickstart](https://www.ory.sh/docs/hydra/self-hosted/quickstart). --- ## 3. Exchange the Authorization Code for an Access Token Once you receive the code
at your redirect URI, exchange it for tokens: bash curl -X POST '<http://localhost:4444/oauth2/token>' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=authorization_code' \ -d 'code=<code_from_query_param>' \ -d 'redirect_uri=<http://localhost/cb>' \ -d 'client_id=<client_id>' \ -d 'client_secret=<client_secret>'
The response will include an access_token
, and if you requested offline_access
, a refresh_token
as well [OAuth2 authorization code flow](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow#web-server-app-and-confidential-client). --- ## 4. (Optional) Introspect the Access Token To verify the token, use the introspection endpoint: bash curl -X POST '<http://localhost:4445/oauth2/introspect>' \ -u '<client_id>:<client_secret>' \ -d 'token=<access_token>'
[Ory Hydra OAuth2 Server Quickstart](https://www.ory.sh/docs/hydra/self-hosted/quickstart) --- Note: - Replace localhost:4444
and localhost:4445
with your actual Hydra public and admin endpoints. - The login and consent screens are handled by your own app or a demo app as described in the docs. If you need more details on any step, let me know!square-napkin-92357
06/09/2025, 10:52 AM<http://localhost:4444/oauth2/auth?response_type=code>
&client_id=<client_id>
&redirect_uri=<http://localhost/cb>
&scope=openid%20offline_access
&state=xyz
brief-egg-61061
06/09/2025, 10:52 AMbrief-egg-61061
06/09/2025, 10:52 AMstate
parameter in the OAuth2 authorization request is a random value generated by the requesting application. Its primary purpose is to prevent cross-site request forgery (CSRF) attacks. When you initiate the authorization request, you generate a random string (for example, xyz
), include it as the state
parameter, and then verify that the same value is returned to your redirect URI after the user authenticates. This ensures the response is not forged or tampered with. From the documentation: > `state`: A random value that is generated by the requesting application to prevent cross-site request forgery (CSRF) attacks [OAuth2 authorization code flow](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow). So, the value of state
should be a securely generated random string unique to each authorization request.square-napkin-92357
06/09/2025, 10:56 AMbrief-egg-61061
06/09/2025, 10:56 AMbrief-egg-61061
06/09/2025, 10:56 AMlogin_challenge
query parameter to the login provider URL when initiating a login flow. Its value is generated by Ory Hydra for each login request and is used by your login provider (the app handling user authentication) to fetch information about the login request and to accept or reject the authentication process. You do not generate this value yourself; it is provided by Ory Hydra as part of the OAuth2 flow. For example, when a user is redirected to your login endpoint, the URL will look like: <https://login.example.org/oauth2-login?login_challenge=7bb518c4>
Here, 7bb518c4
is the value of the OAuth 2.0 Login Request Challenge for that specific login attempt. Your login provider should extract this value from the query parameter and use it to interact with the Ory Hydra Admin API (e.g., to fetch the login request or to accept/reject it) [User login and consent flow](https://www.ory.sh/docs/oauth2-oidc/custom-login-consent/flow) [getOAuth2LoginRequest](https://www.ory.sh/docs/reference/api). In summary: The value of the OAuth 2.0 Login Request Challenge is a unique string generated by Ory Hydra and sent as the login_challenge
query parameter in the login flow URL.square-napkin-92357
06/10/2025, 1:51 AMbrief-egg-61061
06/10/2025, 1:51 AMbrief-egg-61061
06/10/2025, 1:51 AM/admin/clients
) to create a new OAuth2 client: bash curl -X POST '<http://localhost:4445/admin/clients>' \ -H 'Content-Type: application/json' \ -d '{ "client_name": "my app", "grant_types": ["authorization_code"], "redirect_uris": ["<http://localhost/cb>"], "response_types": ["code"], "scope": "openid offline_access", "token_endpoint_auth_method": "client_secret_post" }'
This will return a JSON object with client_id
and client_secret
you’ll use in the next step [Ory Hydra OAuth2 Server Quickstart](https://www.ory.sh/docs/hydra/self-hosted/quickstart). --- ## 2. Perform the Authorization Code Grant (API) ### a. Redirect the User to the Authorization Endpoint Construct a URL and redirect the user to it: <http://localhost:4444/oauth2/auth?response_type=code> &client_id=<client_id> &redirect_uri=<http://localhost/cb> &scope=openid%20offline_access &state=xyz
The user will log in and consent. After that, they’ll be redirected to your redirect_uri
with a code
and state
parameter. --- ### b. Exchange the Authorization Code for an Access Token Once you receive the code
at your redirect URI, exchange it for tokens: bash curl -X POST '<http://localhost:4444/oauth2/token>' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=authorization_code' \ -d 'code=<code_from_query_param>' \ -d 'redirect_uri=<http://localhost/cb>' \ -d 'client_id=<client_id>' \ -d 'client_secret=<client_secret>'
The response will include an access_token
, and if you requested offline_access
, a refresh_token
as well [OAuth2 authorization code flow](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow#web-server-app-and-confidential-client). --- Note: - Replace localhost:4444
and localhost:4445
with your actual Hydra public and admin endpoints. - The login and consent screens are handled by your own app or the demo app as described in the quickstart. If you need more details on any step, let me know!square-napkin-92357
06/10/2025, 2:08 AMcurl -X POST '<http://localhost:4445/admin/clients>' \
-H 'Content-Type: application/json' \
-d '{
"client_name": "my app",
"grant_types": ["authorization_code"],
"redirect_uris": ["<http://localhost/cb>"],
"response_types": ["code"],
"scope": "openid offline_access",
"token_endpoint_auth_method": "client_secret_post"
}
brief-egg-61061
06/10/2025, 2:08 AMbrief-egg-61061
06/10/2025, 2:08 AM<http://localhost:4444/oauth2/auth?response_type=code> &client_id=<client_id> &redirect_uri=<http://localhost/cb> &scope=openid%20offline_access &state=xyz
- Replace <client_id>
with the value you received from the client creation response. - The user will be prompted to log in and consent to the requested scopes. - After successful login and consent, the user will be redirected to your redirect_uri
with a code
and state
parameter [Ory Hydra OAuth2 Server Quickstart](https://www.ory.sh/docs/hydra/self-hosted/quickstart). --- ### 2. Exchange the Authorization Code for an Access Token Once you receive the code
at your redirect URI, exchange it for tokens by making a POST request to the token endpoint: bash curl -X POST '<http://localhost:4444/oauth2/token>' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=authorization_code' \ -d 'code=<code_from_query_param>' \ -d 'redirect_uri=<http://localhost/cb>' \ -d 'client_id=<client_id>' \ -d 'client_secret=<client_secret>'
- Replace <code_from_query_param>
, <client_id>
, and <client_secret>
with the actual values. - The response will include an access_token
, and if you requested offline_access
, a refresh_token
as well [OAuth2 authorization code flow](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow#web-server-app-and-confidential-client). --- Summary: After creating a client, the next step is to start the OAuth2 Authorization Code flow by redirecting the user to the authorization endpoint, then exchanging the received code for an access token.square-napkin-92357
06/10/2025, 2:19 AM{
"client_id": "2d6bb08c-61f3-42c9-8d14-db4a48d085fa",
"client_name": "my app",
"client_secret": "8OLuZe-o6tqIybzjOJREfWNQa3",
"redirect_uris": [
"<https://webapp.md-dev.vnsilicon.cloud/>"
],
"grant_types": [
"authorization_code"
],
"response_types": [
"code"
],
"scope": "openid offline_access",
"audience": [],
"owner": "",
"policy_uri": "",
"allowed_cors_origins": [],
"tos_uri": "",
"client_uri": "",
"logo_uri": "",
"contacts": null,
"client_secret_expires_at": 0,
"subject_type": "public",
"jwks": {},
"token_endpoint_auth_method": "client_secret_post",
"userinfo_signed_response_alg": "none",
"created_at": "2025-06-10T01:56:25Z",
"updated_at": "2025-06-10T01:56:24.794719Z",
"metadata": {},
"registration_access_token": "ory_at_Jey-hTmMsiqaUN6TDxW8E7JOSiUVYFfCAatfq8gP-LI.hM4HDCKzMz4IA6mwKAa7c2A-Nl3-MvaPD2oCeiFqgL0",
"registration_client_uri": "<http://127.0.0.1:4444/oauth2/register/>",
"skip_consent": false,
"skip_logout_consent": null,
"authorization_code_grant_access_token_lifespan": null,
"authorization_code_grant_id_token_lifespan": null,
"authorization_code_grant_refresh_token_lifespan": null,
"client_credentials_grant_access_token_lifespan": null,
"implicit_grant_access_token_lifespan": null,
"implicit_grant_id_token_lifespan": null,
"jwt_bearer_grant_access_token_lifespan": null,
"refresh_token_grant_id_token_lifespan": null,
"refresh_token_grant_access_token_lifespan": null,
"refresh_token_grant_refresh_token_lifespan": null
}
what is the url for user to login?brief-egg-61061
06/10/2025, 2:19 AMbrief-egg-61061
06/10/2025, 2:19 AMhttps://<hydra-public-host>/oauth2/auth?response_type=code &client_id=2d6bb08c-61f3-42c9-8d14-db4a48d085fa &redirect_uri=<https://webapp.md-dev.vnsilicon.cloud/> &scope=openid%20offline_access &state=<random_state>
- Replace <hydra-public-host>
with the hostname of your Ory Hydra public endpoint (for example, localhost:4444
if running locally). - The state
parameter should be a random string generated by your application for CSRF protection. When the user visits this URL, they will be prompted to log in and consent to the requested scopes. After successful authentication and consent, they will be redirected to your specified redirect_uri
with an authorization code [Docs: OAuth2 authorization code flow](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow#web-server-app-and-confidential-client). If you have configured custom login and consent UIs, Ory Hydra will redirect the user to those endpoints as part of the flow [Docs: Custom login and consent flow](https://www.ory.sh/docs/oauth2-oidc/custom-login-consent/flow#flow-steps). If you need the exact login UI URL (for example, if you have a custom login provider), it will be the URL you configured in your Hydra settings for the login flow, and Hydra will append a login_challenge
parameter to it [Docs: Custom login and consent flow](https://www.ory.sh/docs/oauth2-oidc/custom-login-consent/flow#flow-steps). Summary: The user login starts at the /oauth2/auth
endpoint of your Hydra public server, with the appropriate query parameters for your client.square-napkin-92357
06/10/2025, 2:27 AM2025-06-10 09:25:58 GET /login?login_challenge=UveQT-A6iSu8O5oO6I-j4qUK4uXCABeK2ik4wQyg7p5rHP89Ny6XuPkNv6ZV8KIkKuawrIiNmVTX2o19q5PAaFmRdU9-ihCvuAFS9xhR9ucAVaKMt8ENRojxiTyRKcaCJDLbvNd4Wr8h0zowgDyZgw-zxL_y6jCrC1yzMCDfE1rit1tChLf6CP2XykG1ZYl0aE4E7aXmwYd7FtTTNfeAjeNfU1tR_rEyctE1NTNVYf_z1T0TMaxI8FYo3vrtIXekqzF3oZnBYTXeORLoNPrUa86nWPTSdQFUGJci8fHcfGVljchWvnFCMNSZIH4vjluhpd_Ev2lcAMBMhQq_xSUw5U9jsOqwZu8NptEEbi02D7Bjto0EG4fZj1FXFMqy7OL_XXeZ91tmw9dddm6GkTTFTdqW7U_wUkaE8PvI7TNRp6PJwb7iz6oBGqJshbM81vVBFSO_WODFcYi9fk8RJH87w9UzAvIKFRgMwziNdIZwGsNBjOHQYElv20422KOCeH7gA-kFmHOv18ffaag_UQ1l264i4OjFMRun3eK3HQJWozS6Ey4JBPmgKICv9AWcbfO7QhkMbNjFihAIRzENp_CPbIym379tJPWIH99YuQhB1nyeDuqj8UXnALPWd28oeNZGGsV6u2jwg21KVgwhl8UUdYGmLeSkeo0QsZHv1SRCFjnYdtg8ykhYAsTyMSt3SE0drGWF2ajz3opfHXBAjLuED_XPQDstFOnpiqCywe72fzottjIM1cVrx96OTqA6VPvjoVQ98z1GgMhuUGcUiR9NlWonhxQ3o4pBooKukHCKiziQzyonhQ0t8rwXr9crMd4WpVPhdE_sk0AZtddEbZ7NEu2gUDbPwEpSwz04NIy44XnIn0u0AGljtYSZxvoCUWt5dv57g1zIUDX2oNXM-synZKHeaVZvaU6-tldHq4rdVTv-q_OQ-8DX03b2ygkHw87IwYrYH3mWGs6VN4ZuXMphGmMAS21G-3lk3IocUZ941entTj3V4mE0q_bmDyeiNW-SAB7og_GO-oueYGH4GCAGuDl6oTPZD2VZm6qnJN4Hx20gV_Z4u64cK5RkakrrW1cFpVONfjwJctCKUIiNuoUip3n58yVgla7aLALeK9jXOSx7NeY3VlkzA8SfVaRea2ANGD0bWFProv5DV-aJUghXUrdQrmmJFlaDmCzWCOSLWMF7bOFebFzmBqofiyuUYAFBv8Gz0xfcDM2Vb1fNKiOAj8093tFx9ZOWBmu2-oskL-SnZlSTBohGOcG4pKcuyB4qI-2Xo8DCpW7d7-OzGktNmeAtIO0DmbrUax2fSewGefaQU7l2I30qmW5U7QYQbVkiL2IsL3dIatP_oHkBtRQQKsM2sOmQ43rmKr7FmlDScvfX1V0tJwSqSIM%3D 200 24.849 ms - 2154
2025-06-10 09:25:58 Error: Not Found
2025-06-10 09:25:58 at /usr/src/app/lib/app.js:34:10
2025-06-10 09:25:58 at Layer.handle [as handle_request] (/usr/src/app/node_modules/express/lib/router/layer.js:95:5)
2025-06-10 09:25:58 at trim_prefix (/usr/src/app/node_modules/express/lib/router/index.js:323:13)
2025-06-10 09:25:58 at /usr/src/app/node_modules/express/lib/router/index.js:284:7
2025-06-10 09:25:58 at Function.process_params (/usr/src/app/node_modules/express/lib/router/index.js:341:12)
2025-06-10 09:25:58 at next (/usr/src/app/node_modules/express/lib/router/index.js:275:10)
2025-06-10 09:25:58 at /usr/src/app/node_modules/express/lib/router/index.js:641:15
2025-06-10 09:25:58 at next (/usr/src/app/node_modules/express/lib/router/index.js:260:14)
2025-06-10 09:25:58 at Function.handle (/usr/src/app/node_modules/express/lib/router/index.js:174:3)
2025-06-10 09:25:58 at router (/usr/src/app/node_modules/express/lib/router/index.js:47:12)
2025-06-10 09:25:58 GET /favicon.ico 500 6.268 ms - 80
2025-06-10 09:26:09 POST /login 302 19.306 ms - 3400
brief-egg-61061
06/10/2025, 2:27 AMbrief-egg-61061
06/10/2025, 2:28 AMNot Found
error when handling the consent step in your Ory Hydra flow. This typically means that your consent app (the Node.js/Express app handling /consent
and /login
routes) is missing a route or is not correctly set up to handle the consent challenge. Key points from your log: - The app receives a GET request to /login?login_challenge=...
and responds with 200. - Immediately after, there is an Error: Not Found
in your app code. - There is also a GET request to /favicon.ico
returning 500, but this is unrelated to the consent flow. ### What does this mean? According to the Ory documentation, after the login step, Hydra will redirect the user to your consent endpoint (e.g., /consent?consent_challenge=...
). If your Express app does not have a route for /consent
, or if the route is not implemented correctly, you will get a "Not Found" error [User login and consent flow](https://www.ory.sh/docs/oauth2-oidc/custom-login-consent/flow#flow-steps). ### What should you do? 1. Ensure your consent route exists and is implemented. Your Express app should have a route like this: js app.get("/consent", handleConsent) <http://app.post|app.post>("/consent", handleConsentPost)
The handler should process the consent_challenge
parameter, fetch the consent request from Hydra, and render the consent UI or accept the consent request as appropriate [Consent endpoint code example](https://www.ory.sh/docs/oauth2-oidc/custom-login-consent/flow#consent-endpoint-code-example). 2. Check your Hydra configuration. Make sure the consent
URL in your Hydra config points to the correct endpoint of your app (e.g., `http://localhost:3000/consent`) [Configure Ory Network](https://www.ory.sh/docs/hydra/guides/custom-ui-oauth2#configure-ory-network). 3. Reference implementation: You can find a working example of a login and consent app in the [hydra-login-consent-node](https://github.com/ory/hydra-login-consent-node) repository, which you can use as a template. ### Summary The error is because your consent route is missing or not implemented. Add the /consent
route to your app and ensure it follows the Ory flow for handling consent challenges. If you need a code example, you can find one in the Ory documentation and the reference implementation linked above.square-napkin-92357
06/10/2025, 3:13 AMbrief-egg-61061
06/10/2025, 3:13 AMbrief-egg-61061
06/10/2025, 3:13 AMsquare-napkin-92357
06/10/2025, 3:25 AMclient=$(docker compose -f quickstart.yml exec hydra \
hydra create client \
--endpoint <http://127.0.0.1:4445/> \
--format json \
--grant-type client_credentials)
# We parse the JSON response using jq to get the client ID and client secret:
client_id=$(echo $client | jq -r '.client_id')
client_secret=$(echo $client | jq -r '.client_secret')
brief-egg-61061
06/10/2025, 3:25 AMbrief-egg-61061
06/10/2025, 3:25 AMPOST
request to the /admin/clients
endpoint. Here’s how you can do it: bash curl -X POST '<http://127.0.0.1:4445/admin/clients>' \ -H 'Content-Type: application/json' \ -d '{ "client_name": "Client Credentials Demo", "grant_types": ["client_credentials"], "token_endpoint_auth_method": "client_secret_post" }'
The response will be a JSON object containing the client_id
and client_secret
, similar to what you would get from the CLI. You can then parse these values from the JSON response using `jq`: bash client=$(curl -s -X POST '<http://127.0.0.1:4445/admin/clients>' \ -H 'Content-Type: application/json' \ -d '{ "client_name": "Client Credentials Demo", "grant_types": ["client_credentials"], "token_endpoint_auth_method": "client_secret_post" }') client_id=$(echo $client | jq -r '.client_id') client_secret=$(echo $client | jq -r '.client_secret')
This approach directly mirrors the CLI workflow, but uses the API instead [Hydra API Reference](https://www.ory.sh/docs/hydra/reference/api) [Ory API Reference](https://www.ory.sh/docs/reference/api).square-napkin-92357
06/10/2025, 3:28 AMdocker compose -f quickstart.yml exec hydra \
hydra perform client-credentials \
--endpoint <http://127.0.0.1:4444/> \
--client-id "$client_id" \
--client-secret "$client_secret"
ACCESS TOKEN ory_at_ZDTkKci59rH_8KlZlRjIek0812n9oPsvJX_nTdptGt0.bbpFutv5CsfjHzs8QrsnmPZ-0VxgwPvg9jgw1DQaYNg
REFRESH TOKEN <empty>
ID TOKEN <empty>
EXPIRY 2022-06-27 11:50:28.244046504 +0000 UTC m=+3599.059213960
brief-egg-61061
06/10/2025, 3:28 AMbrief-egg-61061
06/10/2025, 3:28 AMhydra perform client-credentials
CLI command using the API, you need to make a POST
request to the /oauth2/token
endpoint on the public port (typically 4444
). Here’s how you can do it using the API: bash curl -X POST '<http://127.0.0.1:4444/oauth2/token>' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=client_credentials' \ -d 'client_id='"$client_id"'' \ -d 'client_secret='"$client_secret"'
This will return a JSON response containing the access_token
, and (for the client credentials flow) the refresh_token
and id_token
fields will be empty, just like in the CLI output [OAuth2 client credentials flow](https://www.ory.sh/docs/oauth2-oidc/client-credentials) [Ory Hydra OAuth2 Server Quickstart](https://www.ory.sh/docs/hydra/self-hosted/quickstart). You can also use HTTP Basic authentication by sending the client_id
and client_secret
in the Authorization
header, as described in the documentation: bash curl -X POST '<http://127.0.0.1:4444/oauth2/token>' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -u "$client_id:$client_secret" \ -d 'grant_type=client_credentials'
Both methods are supported by Ory Hydra and Ory Network [OAuth2 client credentials flow](https://www.ory.sh/docs/oauth2-oidc/client-credentials).square-napkin-92357
06/10/2025, 3:36 AMdocker compose -f quickstart.yml exec hydra \
hydra introspect token \
--format json-pretty \
--endpoint <http://127.0.0.1:4445/> \
UDYMha9TwsMBejEvKfnDOXkhgkLsnmUNYVQDklT5bD8.ZNpuNRC85erbIYDjPqhMwTinlvQmNTk_UvttcLQxFJY
{
"active": true,
"client_id": "24451202-afa7-4278-98ce-8d40f421afec",
"exp": 1656330629,
"iat": 1656327029,
"iss": "<http://127.0.0.1:4444>",
"nbf": 1656327029,
"sub": "24451202-afa7-4278-98ce-8d40f421afec",
"token_type": "Bearer",
"token_use": "access_token"
}
brief-egg-61061
06/10/2025, 3:36 AMbrief-egg-61061
06/10/2025, 3:36 AMhydra introspect token
CLI command using the API, you should make a POST
request to the /admin/oauth2/introspect
endpoint on the admin port (typically 4445
). Here is how you can do it: bash curl -X POST '<http://127.0.0.1:4445/admin/oauth2/introspect>' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'token=UDYMha9TwsMBejEvKfnDOXkhgkLsnmUNYVQDklT5bD8.ZNpuNRC85erbIYDjPqhMwTinlvQmNTk_UvttcLQxFJY'
The response will be a JSON object similar to: json { "active": true, "client_id": "24451202-afa7-4278-98ce-8d40f421afec", "exp": 1656330629, "iat": 1656327029, "iss": "<http://127.0.0.1:4444>", "nbf": 1656327029, "sub": "24451202-afa7-4278-98ce-8d40f421afec", "token_type": "Bearer", "token_use": "access_token" }
This matches the output you would get from the CLI with --format json-pretty
[Ory Hydra OAuth2 Server Quickstart](https://www.ory.sh/docs/hydra/self-hosted/quickstart) [Hydra API Reference](https://www.ory.sh/docs/hydra/reference/api).square-napkin-92357
06/10/2025, 3:41 AMcode_client=$(docker compose -f quickstart.yml exec hydra \
hydra create client \
--endpoint <http://127.0.0.1:4445> \
--grant-type authorization_code,refresh_token \
--response-type code,id_token \
--format json \
--scope openid --scope offline \
--redirect-uri <http://127.0.0.1:5555/callback>)
code_client_id=$(echo $code_client | jq -r '.client_id')
code_client_secret=$(echo $code_client | jq -r '.client_secret')
brief-egg-61061
06/10/2025, 3:41 AMbrief-egg-61061
06/10/2025, 3:41 AMPOST
request to the /admin/clients
endpoint. Here’s how you can do it: bash curl -X POST '<http://127.0.0.1:4445/admin/clients>' \ -H 'Content-Type: application/json' \ -d '{ "client_name": "Authorization Code Client", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code", "id_token"], "scope": "openid offline", "redirect_uris": ["<http://127.0.0.1:5555/callback>"] }'
The response will be a JSON object containing the client_id
and client_secret
, which you can extract using `jq`: bash code_client=$(curl -s -X POST '<http://127.0.0.1:4445/admin/clients>' \ -H 'Content-Type: application/json' \ -d '{ "client_name": "Authorization Code Client", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code", "id_token"], "scope": "openid offline", "redirect_uris": ["<http://127.0.0.1:5555/callback>"] }') code_client_id=$(echo $code_client | jq -r '.client_id') code_client_secret=$(echo $code_client | jq -r '.client_secret')
This approach directly mirrors the CLI workflow, but uses the API instead [Ory Hydra OAuth2 Server Quickstart](https://www.ory.sh/docs/hydra/self-hosted/quickstart).square-napkin-92357
06/10/2025, 3:44 AMdocker compose -f quickstart.yml exec hydra \
hydra perform authorization-code \
--client-id $code_client_id \
--client-secret $code_client_secret \
--endpoint <http://127.0.0.1:4444/> \
--port 5555 \
--scope openid --scope offline
Setting up home route on <http://127.0.0.1:5555/>
Setting up callback listener on <http://127.0.0.1:5555/callback>
Press ctrl + c on Linux / Windows or cmd + c on OSX to end the process.
If your browser doesn't open automatically, navigate to:
<http://127.0.0.1:5555/>
brief-egg-61061
06/10/2025, 3:44 AMbrief-egg-61061
06/10/2025, 3:44 AMhydra perform authorization-code
CLI command using the API, you need to manually implement the OAuth2 Authorization Code flow using HTTP requests. Here are the steps, based strictly on the Ory Hydra documentation: --- ### 1. Redirect the User to the Authorization Endpoint Construct a URL and redirect the user to it (for example, by having them visit this link in their browser): <http://127.0.0.1:4444/oauth2/auth?response_type=code> &client_id=<code_client_id> &redirect_uri=<http://127.0.0.1:5555/callback> &scope=openid%20offline &state=<random_state>
- Replace <code_client_id>
with your actual client ID. - The state
parameter should be a securely generated random string. - The user will be prompted to log in and consent. After that, they’ll be redirected to your redirect_uri
with a code
and state
parameter [Ory Hydra OAuth2 Server Quickstart](https://www.ory.sh/docs/hydra/self-hosted/quickstart). --- ### 2. Handle the Redirect and Extract the Authorization Code Your application should listen on <http://127.0.0.1:5555/callback>
and extract the code
parameter from the query string. --- ### 3. Exchange the Authorization Code for Tokens Make a POST request to the token endpoint: bash curl -X POST '<http://127.0.0.1:4444/oauth2/token>' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=authorization_code' \ -d 'code=<code_from_query_param>' \ -d 'redirect_uri=<http://127.0.0.1:5555/callback>' \ -d 'client_id=<code_client_id>' \ -d 'client_secret=<code_client_secret>'
- Replace <code_from_query_param>
, <code_client_id>
, and <code_client_secret>
with the actual values. - The response will include an access_token
, and if you requested offline
scope, a refresh_token
as well [OAuth2 authorization code flow](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow#web-server-app-and-confidential-client). --- Summary: You must implement the browser redirect, callback handler, and token exchange steps yourself using HTTP requests and your application logic. The CLI command automates this, but the API requires you to handle each step as described above.square-napkin-92357
06/10/2025, 4:19 AMcurl --location '<http://127.0.0.1:4444/oauth2/token>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: csrf_token_24aea333b35d28c822e467e182874097a6d2ca58de8e4a3a477db6d2b6626306=ZC5b0zWAuUUjrISIb6G3/Je0kzQsEZaZjXku80zjvkg=' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=ory_ac_lRhKNpUxPaSZ5VI6j0V3n0MH1uDWNRvEKqXasOeqIMU.IufSFu52Etaf5klRV7UgjnicCbUDipr78QDoH3nGDa4' \
--data-urlencode 'redirect_uri=<http://127.0.0.1:5555/callback>' \
--data-urlencode 'client_id=e4a0b14a-d539-4845-87d6-05d98dd3cd7d' \
--data-urlencode 'client_secret=nIz9P5zUN4TOpkcEp0F_SolBnu'
i get error
{
"error": "invalid_client",
"error_description": "Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The OAuth 2.0 Client supports client authentication method 'client_secret_basic', but method 'client_secret_post' was requested. You must configure the OAuth 2.0 client's 'token_endpoint_auth_method' value to accept 'client_secret_post'."
}
brief-egg-61061
06/10/2025, 4:19 AMbrief-egg-61061
06/10/2025, 4:20 AM"Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The OAuth 2.0 Client supports client authentication method 'client_secret_basic', but method 'client_secret_post' was requested. You must configure the OAuth 2.0 client's 'token_endpoint_auth_method' value to accept 'client_secret_post'."
means that your OAuth2 client is currently configured to use client_secret_basic
for authentication at the token endpoint, but your curl
request is using client_secret_post
(sending the client credentials in the POST body). How to resolve: You have two options: --- ### 1. Use client_secret_basic
in your request Instead of sending client_id
and client_secret
in the POST body, use HTTP Basic Auth. For curl
, this means using the -u
flag: bash curl --location '<http://127.0.0.1:4444/oauth2/token>' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode 'code=...' \ --data-urlencode 'redirect_uri=<http://127.0.0.1:5555/callback>' \ -u 'e4a0b14a-d539-4845-87d6-05d98dd3cd7d:nIz9P5zUN4TOpkcEp0F_SolBnu'
This matches the default token_endpoint_auth_method
for new clients, which is client_secret_basic
[Client auth fails because Wrong token_endpoint_auth_method](https://www.ory.sh/docs/hydra/debug/token-endpoint-auth-method). --- ### 2. Change the client to accept client_secret_post
If you want to keep sending the credentials in the POST body, you must update your client to allow client_secret_post
as the authentication method. You can do this via the CLI or API: Using the API: bash curl -X PUT '<http://127.0.0.1:4445/admin/clients/e4a0b14a-d539-4845-87d6-05d98dd3cd7d>' \ -H 'Content-Type: application/json' \ -d '{ "token_endpoint_auth_method": "client_secret_post" }'
Or, when creating the client, set "token_endpoint_auth_method": "client_secret_post"
[Client auth fails because Wrong token_endpoint_auth_method](https://www.ory.sh/docs/hydra/debug/token-endpoint-auth-method). --- Summary: You must either use HTTP Basic Auth (client_secret_basic
) in your token request, or update your client to accept client_secret_post
. The error is due to a mismatch between the client configuration and how you are sending credentials in your request.square-napkin-92357
06/10/2025, 4:22 AM{
"access_token": "ory_at_SDXaYB1cYrlw2UJCtDS35t0Zmi2ohgjJcQeiVrISvG4.BicIotHAbBJuXq3inVaYKaHV1lMOI3BQHyHctuzxs08",
"expires_in": 3599,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjUyNGYwM2EyLTQyNDAtNGFlZS05ZGMzLTIwNjA1N2RkZDcwZSIsInR5cCI6IkpXVCJ9.eyJhY3IiOiIwIiwiYXRfaGFzaCI6IlZXTmFpNnYxcEZuRm9VZTBYSHkwbFEiLCJhdWQiOlsiZTRhMGIxNGEtZDUzOS00ODQ1LTg3ZDYtMDVkOThkZDNjZDdkIl0sImF1dGhfdGltZSI6MTc0OTUyODc4MywiZXhwIjoxNzQ5NTMyODcwLCJpYXQiOjE3NDk1MjkyNzAsImlzcyI6Imh0dHA6Ly8xMjcuMC4wLjE6NDQ0NCIsImp0aSI6IjhjMGM5NGRlLTU0MTgtNGM0NS1hMzc4LTMwMTRiYTlkZDM3YSIsInJhdCI6MTc0OTUyODc3NSwic2lkIjoiYzNmOTZmMjItZTNlZS00NmM3LWI1NGUtZGZjOTdlNDYxY2E3Iiwic3ViIjoiZm9vQGJhci5jb20ifQ.WUzq2B3UF4esD8rF4ByOtZagiBeJbxxt2UXdAxt2cpR1f1LHUsyjgfQ3pbD0rHwZ_DGpC9azLD_WWUGA5qKHW4wxEo266UX9ZvQtGpqDYiIVhUeG9P7u4r7rkfyyO7pxNnY8_6uppB2UgwVzO0URJ0Iu-FjFNZ1tykfbg8I0-YDtxeEjN8U3lzpbhtAUgI_VbyuJ5IPtj814ufn9LlmQas4BsMgUatW8V65lU655oRjOZ63EWaFBLAdC_VtCBI4-IS0fdVgYNa4uIb8NYR3S4YlIKdhqRcW0phA17P6k7k3RGHzqAY6qM0ek3sGdTL8fqZ5Q8-2FbCvdPyWxHLxE-A_pnf2xKTC7iHBNYSZ4qnogi54NF_QwUmEOZtlQKxP11WrMdInlJfF3xB59utzFpMmCxKeHp8_DzUxqTuUL7-71RYvd68xJboiS0-5P296rtA9QwIq7bYX7eFrKFNhqLP4AC8xdjdW8MYVkr-n2Dm1bNjYcgLNZBhXQtalG3hELV0tWV7HWCjLdz-y8dO6cAnB9aKjNd3lSOduGmkczKAdlh13Yu45KlsbdvbTgG4mLDyBJhV_BYQ9MRENnmUy7sHfQ08NxIj2emXEYOEzfNQK6N_vmsUkDe22-NvH7afbRXOPWmd5191zfNRKdNHeEBDJc32GvOlaqOIhXknPeUpo",
"refresh_token": "ory_rt_wQ4QkqxoRoF-5_FTh1YFrbWSBOhtspWHcz-LhN_nsCo.ugWic-7SN3zRO_WxjMEeCtIkFzujk8mGexTJRqlAQLw",
"scope": "openid offline",
"token_type": "bearer"
}
how about the next step?brief-egg-61061
06/10/2025, 4:23 AMbrief-egg-61061
06/10/2025, 4:23 AMaccess_token
, id_token
, and refresh_token
from Ory Hydra using the OAuth2 Authorization Code flow. Here’s what you can do next: --- ### 1. Use the Access Token to Call Protected APIs You can use the access_token
to access protected resources by including it in the Authorization
header of your API requests: javascript const fetch = require("node-fetch") const accessToken = "your_access_token_here" fetch("<https://api.example.com/resource>", { headers: { Authorization: "Bearer " + accessToken, }, }) .then((response) => response.json()) .then((data) => console.log(data)) .catch((error) => console.error(error))
This is the standard way to use the access token to access APIs protected by Ory OAuth2 & OpenID Connect [Accessing APIs](https://www.ory.sh/docs/oauth2-oidc/overview/oauth2-concepts#accessing-apis). --- ### 2. Use the ID Token The id_token
is a JWT that contains information about the authenticated user. You can decode and validate it using the public keys from your Ory Hydra instance: - Public keys are available at: http://<your-hydra-host>/.well-known/jwks.json
- This allows you to verify the token’s signature and extract user claims [Modifying the authorization code flow](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow#modifying-the-authorization-code-flow). --- ### 3. Use the Refresh Token When the access_token
expires, you can use the refresh_token
to obtain a new access token without requiring the user to re-authenticate: javascript const endpoint = "<http://127.0.0.1:4444/oauth2/token>" const refreshToken = "your_refresh_token" const clientId = "your_client_id" const clientSecret = "your_client_secret" const params = new URLSearchParams({ grant_type: "refresh_token", refresh_token: refreshToken, client_id: clientId, client_secret: clientSecret, }) fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body: params.toString(), }) .then((response) => response.json()) .then((data) => { console.log("New access token:", data.access_token) console.log("New ID token:", data.id_token) console.log("New refresh token:", data.refresh_token) }) .catch((error) => { console.error(error) })
[OAuth2 refresh token grant](https://www.ory.sh/docs/oauth2-oidc/refresh-token-grant) --- If you need to introspect or validate the access token, you can use the introspection endpoint as described in the documentation. Let me know if you need guidance on a specific next step!square-napkin-92357
06/10/2025, 4:25 AMrefresh_token
to obtain a new access token without requiring the user to re-authenticatebrief-egg-61061
06/10/2025, 4:25 AMbrief-egg-61061
06/10/2025, 4:25 AMrefresh_token
to obtain a new access token without requiring the user to re-authenticate, you can make a POST request to the /oauth2/token
endpoint with the grant_type
set to refresh_token
. Here is the curl
command based on the official Ory documentation: bash curl -X POST '<http://127.0.0.1:4444/oauth2/token>' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=refresh_token' \ -d 'refresh_token=<your_refresh_token>' \ -d 'client_id=<your_client_id>' \ -d 'client_secret=<your_client_secret>'
Replace <your_refresh_token>
, <your_client_id>
, and <your_client_secret>
with your actual values. This will return a new access token, and possibly a new refresh token and ID token if applicable [OAuth2 refresh token grant](https://www.ory.sh/docs/oauth2-oidc/refresh-token-grant).square-napkin-92357
06/10/2025, 4:29 AMcurl --location '<http://127.0.0.1:4444/oauth2/token>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic ZTRhMGIxNGEtZDUzOS00ODQ1LTg3ZDYtMDVkOThkZDNjZDdkOm5JejlQNXpVTjRUT3BrY0VwMEZfU29sQm51' \
--header 'Cookie: csrf_token_24aea333b35d28c822e467e182874097a6d2ca58de8e4a3a477db6d2b6626306=ZC5b0zWAuUUjrISIb6G3/Je0kzQsEZaZjXku80zjvkg=' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'refresh_token=ory_at_SDXaYB1cYrlw2UJCtDS35t0Zmi2ohgjJcQeiVrISvG4.BicIotHAbBJuXq3inVaYKaHV1lMOI3BQHyHctuzxs08' \
--data-urlencode 'client_id=e4a0b14a-d539-4845-87d6-05d98dd3cd7d' \
--data-urlencode 'client_secret=nIz9P5zUN4TOpkcEp0F_SolBnu'
i get error
{
"error": "invalid_client",
"error_description": "Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The OAuth 2.0 Client supports client authentication method 'client_secret_basic', but method 'client_secret_post' was requested. You must configure the OAuth 2.0 client's 'token_endpoint_auth_method' value to accept 'client_secret_post'."
}
brief-egg-61061
06/10/2025, 4:29 AMbrief-egg-61061
06/10/2025, 4:29 AM"Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The OAuth 2.0 Client supports client authentication method 'client_secret_basic', but method 'client_secret_post' was requested. You must configure the OAuth 2.0 client's 'token_endpoint_auth_method' value to accept 'client_secret_post'."
means that your client is configured to use client_secret_basic
for authentication, but your request is mixing both client_secret_basic
(via the Authorization
header) and client_secret_post
(by sending client_id
and client_secret
in the POST body). According to the Ory Hydra documentation, you must use only one authentication method, and it must match the client's configuration. How to fix: - For client_secret_basic
(default): Do not include client_id
and client_secret
in the POST body. Only use the Authorization
header: bash curl --location '<http://127.0.0.1:4444/oauth2/token>' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --header 'Authorization: Basic ZTRhMGIxNGEtZDUzOS00ODQ1LTg3ZDYtMDVkOThkZDNjZDdkOm5JejlQNXpVTjRUT3BrY0VwMEZfU29sQm51' \ --data-urlencode 'grant_type=refresh_token' \ --data-urlencode 'refresh_token=ory_at_SDXaYB1cYrlw2UJCtDS35t0Zmi2ohgjJcQeiVrISvG4.BicIotHAbBJuXq3inVaYKaHV1lMOI3BQHyHctuzxs08'
- For `client_secret_post`: If you want to send client_id
and client_secret
in the POST body, you must update your client to use client_secret_post
as the `token_endpoint_auth_method`: bash curl -X PUT '<http://127.0.0.1:4445/admin/clients/e4a0b14a-d539-4845-87d6-05d98dd3cd7d>' \ -H 'Content-Type: application/json' \ -d '{"token_endpoint_auth_method": "client_secret_post"}'
Then, you can use: bash curl --location '<http://127.0.0.1:4444/oauth2/token>' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=refresh_token' \ --data-urlencode 'refresh_token=ory_at_SDXaYB1cYrlw2UJCtDS35t0Zmi2ohgjJcQeiVrISvG4.BicIotHAbBJuXq3inVaYKaHV1lMOI3BQHyHctuzxs08' \ --data-urlencode 'client_id=e4a0b14a-d539-4845-87d6-05d98dd3cd7d' \ --data-urlencode 'client_secret=nIz9P5zUN4TOpkcEp0F_SolBnu'
Summary: You must use the authentication method that matches your client's token_endpoint_auth_method
setting. Mixing both methods in a single request will result in an error. This is explicitly described in the Ory Hydra documentation: > "If you try to authorize with the client credentials in the POST body, the authentication process will fail. To allow a client to perform the POST authorization scheme, you must set 'token_endpoint_auth_method' to 'client_secret_post'." [Client auth fails because Wrong token_endpoint_auth_method](https://www.ory.sh/docs/hydra/debug/token-endpoint-auth-method)square-napkin-92357
06/10/2025, 4:38 AMbrief-egg-61061
06/10/2025, 4:38 AMbrief-egg-61061
06/10/2025, 4:39 AMaccess_token
expire sooner in Ory Hydra, you need to configure the access token's lifespan. You can do this either globally or per OAuth2 client. To set the access token expiration globally: Use the Ory CLI to patch the configuration: bash ory patch oauth2-config --project <project-id> --workspace <workspace-id> \ --replace "/ttl/access_token=\"5m\"" \ --format yaml
This example sets the access token lifespan to 5 minutes. Replace the value as needed [Configure token expiration time](https://www.ory.sh/docs/hydra/guides/client-token-expiration). To set the access token expiration for a specific client: You can use the API to set the lifespan for a specific client: bash curl -X PUT '<http://localhost:4445/admin/clients/<client_id>/lifespans>' \ -H 'Content-Type: application/json' \ -d '{ "authorization_code_grant_access_token_lifespan": "5m" }'
This will make the access tokens issued to that client expire after 5 minutes [Ory API Reference](https://www.ory.sh/docs/reference/api). You can also use the SDK as shown in the documentation to set lifespans programmatically. Summary: To make access_token
expire, reduce its lifespan in the configuration—either globally or per client—using the CLI, API, or SDK.square-napkin-92357
06/10/2025, 4:40 AMbrief-egg-61061
06/10/2025, 4:40 AMbrief-egg-61061
06/10/2025, 4:40 AMbash curl -X POST '<http://127.0.0.1:4444/oauth2/revoke>' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -u '<client_id>:<client_secret>' \ -d 'token=<access_token>'
- Replace <client_id>
and <client_secret>
with your OAuth2 client credentials. - Replace <access_token>
with the token you want to revoke. This endpoint supports revoking both access and refresh tokens. After revocation, the token will be invalid for further use [revokeOAuth2Token](https://www.ory.sh/docs/hydra/reference/api). > Note: Revoking an access token does not end the user's session or log them out from the identity provider. It only invalidates the specific token. If you need to revoke all tokens for a client, you can use the admin endpoint to delete all access tokens for a client: bash curl -X DELETE '<http://127.0.0.1:4445/admin/oauth2/tokens?client_id=<client_id>>'
This deletes all access tokens issued to the specified client [deleteOAuth2Token](https://www.ory.sh/docs/hydra/reference/api). If you need to revoke login sessions (not just tokens), there are separate endpoints for that as well. If you need more details or a different type of logout, please specify!square-napkin-92357
06/10/2025, 4:45 AMhttp-server.authentication.oauth2.issuer=
http-server.authentication.oauth2.client-id=
http-server.authentication.oauth2.client-secret=
brief-egg-61061
06/10/2025, 4:45 AMbrief-egg-61061
06/10/2025, 4:46 AMhttp-server.authentication.oauth2.issuer= http-server.authentication.oauth2.client-id= http-server.authentication.oauth2.client-secret=
However, based on standard OAuth2/OIDC practices and the Ory Hydra documentation, typically: - http-server.authentication.oauth2.issuer
would be set to the public URL of your Ory Hydra instance (for example, <http://localhost:4444>
or your deployed Hydra public endpoint). - http-server.authentication.oauth2.client-id
would be the client_id
of the OAuth2 client you created in Hydra for Trino. - http-server.authentication.oauth2.client-secret
would be the client_secret
associated with that client. Since the knowledge sources do not provide a Trino-specific integration example or confirm these values, please consult the Trino and Ory Hydra documentation for precise integration steps and verify the correct endpoints and credentials for your setup.square-napkin-92357
06/10/2025, 5:37 AMbrief-egg-61061
06/10/2025, 5:37 AMbrief-egg-61061
06/10/2025, 5:37 AMclient_id
and client_secret
are "fixed" in the sense of being unchangeable. However, according to the Ory Hydra documentation, when you create an OAuth2 client, the client_id
and client_secret
are generated and returned to you. These values remain the same for that client unless you explicitly update or rotate them using the API or CLI. If you delete and recreate the client, new values will be generated. So, for a given OAuth2 client in Ory Hydra, the client_id
and client_secret
are fixed (do not change) unless you take action to update or rotate them. The knowledge sources do not mention any automatic rotation or change of these credentials after client creation [Manage OAuth 2.0 and OpenID Connect clients](https://www.ory.sh/docs/hydra/guides/oauth2-clients).square-napkin-92357
06/10/2025, 5:40 AMbrief-egg-61061
06/10/2025, 5:40 AMbrief-egg-61061
06/10/2025, 5:40 AMGET /admin/clients/{id}
Replace {id}
with the client ID you want to retrieve. This endpoint will return the details of the specified OAuth2 client. Note that this endpoint never returns the client secret. Example using curl: bash curl -X GET '<http://localhost:4445/admin/clients/<client_id>>'
Replace <client_id>
with your actual client ID. This operation does not require authentication by default in Ory Hydra [Hydra API Reference – getOAuth2Client](https://www.ory.sh/docs/hydra/reference/api). > Note: If you are using Ory Network or another Ory product, authentication may be required [Ory API Reference – getOAuth2Client](https://www.ory.sh/docs/reference/api).