Skip to content

Token exchange fails (invalid_grant) when login URL has a query string #14

Closed

Description

@melvincarvalho

Summary

Login fails with 400 invalid_grant at the token endpoint whenever the app URL has a query string at sign-in time (e.g. /apps/tasks/?tracker=one-data.jsonld).

Cause

login() uses the full URL including the query as the redirect URI, both for dynamic client registration and for the authorization request:

const sanitizedRedirect = redirectUrl.origin + redirectUrl.pathname + redirectUrl.search

But handleRedirectFromLogin() sends a redirect URI without the query in the token request:

redirect_uri: url.origin + url.pathname,

RFC 6749 §4.1.3 requires the token request's redirect_uri to be identical to the one in the authorization request, so the IdP rejects the code exchange.

Repro

  1. Open a solid-oidc app (e.g. via xlogin) at a URL with a query string, e.g. http://localhost:5444/public/apps/tasks/?tracker=one-data.jsonld
  2. Sign in to a JSS / jspod IdP
  3. After the redirect back, POST /idp/token returns 400 {"error":"invalid_grant","error_description":"grant request is invalid"}, and the user is left signed out

The registered client shows redirect_uris: ["http://localhost:5444/public/apps/tasks/?tracker=one-data.jsonld"], while the token request sends http://localhost:5444/public/apps/tasks/.

Signing in from the same page without a query string works.

Proposed fix

Save the exact redirect URI in sessionStorage during login() (e.g. solid_oidc_redirect_uri) and reuse it in the token request. If it's missing, fall back to origin + pathname + search (after code/iss/state are stripped). Clear the key along with the other solid_oidc_* keys.

Affects 0.0.9 (as loaded by xlogin 0.0.15 via esm.sh).

Activity

  1. added 3 commits that reference this issue on Oct 4, 2026
    981603e
    14143ba
    b7bdacb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions