mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(core): refactor oidc error response query param (#6525)
refactor oidc error reponse query param
This commit is contained in:
parent
3d3a220306
commit
8beb758771
2 changed files with 25 additions and 26 deletions
|
@ -2,24 +2,22 @@
|
|||
"@logto/core": patch
|
||||
---
|
||||
|
||||
introduce new `error_code_key` query parameter in the `koaErrorHandler`.
|
||||
introduce new `parse_error` query parameter flag. The value of `parse_error` can only be `false`.
|
||||
|
||||
By default, Logto uses `code` as the error code key in the error response body.
|
||||
For some third-party connectors, like Google, `code` is considered as a reserved OIDC key,
|
||||
can't be used as the error code key in the error response body. Any oidc error response body containing `code` will be rejected by Google.
|
||||
By default, Logto returns the parsed error code and error description in all the `RequestError` error responses. This is to ensure the error responses are consistent and easy to understand.
|
||||
|
||||
To workaround this, we introduce a new `error_code_key` query parameter to customize the error code key in the error response body.
|
||||
In the oidc requests, if the `error_code_key` is present in the query string, we will use the value of `error_code_key` as the error code key in the error response body.
|
||||
However, when integrating Logto with Google OAuth, the error response body containing `code` will be rejected by Google. `code` is considered as a reserved OIDC key, can't be used as the error code key in the error response body.
|
||||
|
||||
To workaround this, we add a new `parse_error` query parameter flag. When parsing the OIDC error body, if the `parse_error` is set to false, only oidc error body will be returned.
|
||||
|
||||
example:
|
||||
|
||||
```curl
|
||||
curl -X POST "http://localhost:3001/oidc/token?error_code_key=error_code"
|
||||
curl -X POST "http://localhost:3001/oidc/token?parse_error=false"
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"error_code": "oidc.invalid_grant",
|
||||
"error": "invalid_grant",
|
||||
"error_description": "Invalid value for parameter 'code': 'invalid_code'."
|
||||
}
|
||||
|
|
|
@ -97,9 +97,22 @@ export default function koaOidcErrorHandler<StateT, ContextT>(): Middleware<Stat
|
|||
ctx.body = errorOut(error);
|
||||
}
|
||||
|
||||
// Parse the `parse_error` from the query string.
|
||||
// If the `parse_error` is set to false, only returns the original oidc error body.
|
||||
// For some third-party connectors, like Google, `code` is considered as a reserved OIDC key,
|
||||
// we can't return the error body containing `code` in the error response.
|
||||
const queryParametersResult = z
|
||||
.object({
|
||||
parse_error: z.literal('false').optional(),
|
||||
})
|
||||
.safeParse(ctx.query);
|
||||
|
||||
const returnRawError =
|
||||
queryParametersResult.success && queryParametersResult.data.parse_error === 'false';
|
||||
|
||||
// This is the only way we can check if the error is handled by the oidc-provider, because
|
||||
// oidc-provider doesn't call `renderError` when the request prefers JSON response.
|
||||
if (ctx.status >= 400 && isObject(ctx.body)) {
|
||||
if (ctx.status >= 400 && isObject(ctx.body) && !returnRawError) {
|
||||
const parsed = z
|
||||
.object({
|
||||
error: z.string(),
|
||||
|
@ -113,26 +126,14 @@ export default function koaOidcErrorHandler<StateT, ContextT>(): Middleware<Stat
|
|||
const code = isSessionNotFound(data.error_description)
|
||||
? 'session.not_found'
|
||||
: `oidc.${data.error}`;
|
||||
|
||||
const uri = errorUris[data.error];
|
||||
|
||||
// Parse the `error_code_key` from the query string.
|
||||
// This is used to customize the error key in the response body.
|
||||
// For some third-party connectors, like Google, `code` is considered as a reserved OIDC key,
|
||||
// can't be used as the error code key in the error response body.
|
||||
// We add `error_code_key` to the query string to customize the error key in the response body.
|
||||
const errorKeyQueryResult = z
|
||||
.object({
|
||||
error_code_key: z.string().optional(),
|
||||
})
|
||||
.safeParse(ctx.query);
|
||||
|
||||
const errorKey = errorKeyQueryResult.success
|
||||
? errorKeyQueryResult.data.error_code_key ?? 'code'
|
||||
: 'code';
|
||||
|
||||
ctx.body = {
|
||||
[errorKey]: code,
|
||||
message: i18next.t(['errors:' + code, 'errors:oidc.provider_error_fallback'], { code }),
|
||||
code,
|
||||
message: i18next.t(['errors:' + code, 'errors:oidc.provider_error_fallback'], {
|
||||
code,
|
||||
}),
|
||||
error_uri: uri,
|
||||
...ctx.body,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue