<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: marsdiscovery</title>
    <description>The latest articles on DEV Community by marsdiscovery (@marsdiscovery_3d15f443c16).</description>
    <link>https://dev.to/marsdiscovery_3d15f443c16</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3967735%2Febcffc8c-37bd-4c4d-a217-71fba4ca3392.jpg</url>
      <title>DEV Community: marsdiscovery</title>
      <link>https://dev.to/marsdiscovery_3d15f443c16</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marsdiscovery_3d15f443c16"/>
    <language>en</language>
    <item>
      <title>The redirect_uri matched in the dashboard. OAuth still failed.</title>
      <dc:creator>marsdiscovery</dc:creator>
      <pubDate>Thu, 04 Jun 2026 07:18:26 +0000</pubDate>
      <link>https://dev.to/marsdiscovery_3d15f443c16/the-redirecturi-matched-in-the-dashboard-oauth-still-failed-50hl</link>
      <guid>https://dev.to/marsdiscovery_3d15f443c16/the-redirecturi-matched-in-the-dashboard-oauth-still-failed-50hl</guid>
      <description>&lt;p&gt;We spent an afternoon convinced the identity provider was broken. Login worked locally. Staging failed with the usual vague error — redirect mismatch, invalid request, pick your vendor wording.&lt;/p&gt;

&lt;p&gt;The redirect_uri in our admin console was copied from the ticket. Character for character, it looked identical to what the browser sent. No trailing slash debate. No http vs https surprise.&lt;/p&gt;

&lt;p&gt;Then I dumped the authorize URL from the network tab and compared it to what we had registered.&lt;/p&gt;

&lt;p&gt;One query value had been encoded twice. Another used + for a space in a place our stack later read as a literal plus. The path wasn't wrong. The encoding layers were fighting each other.&lt;/p&gt;

&lt;p&gt;This is the boring class of bug: nothing shows up in a unit test because each function "works" in isolation. The failure only appears when a full URL travels through a form, a framework helper, and a provider that compares strings literally.&lt;/p&gt;

&lt;p&gt;What I watch for now:&lt;/p&gt;

&lt;p&gt;Before blaming the IdP, decode the authorize URL once in a sane viewer. I want to see each query key and value split apart, not a single opaque percent soup.&lt;/p&gt;

&lt;p&gt;Plus vs %20. application/x-www-form-urlencoded treats + as space. Generic URI encoding uses %20. Mix those rules in one redirect chain and you get ghosts.&lt;/p&gt;

&lt;p&gt;Nested URLs. Some flows put a return URL inside a query parameter. Encode the inner URL as a component, not as "the whole string again with extra % on the %."&lt;/p&gt;

&lt;p&gt;One-line error JSON from the token endpoint still shows up in the same incident. Pretty-printing it once saves ten minutes of guessing whether the problem is OAuth or your own handler.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjazxciaz3eehclcrxapo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjazxciaz3eehclcrxapo.png" alt=" " width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Browser tabs I keep for these checks — one job per page, local processing, no account for a two-minute look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devcove.dev/en/tools/url-encoder/" rel="noopener noreferrer"&gt;https://devcove.dev/en/tools/url-encoder/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devcove.dev/en/tools/json-formatter/" rel="noopener noreferrer"&gt;https://devcove.dev/en/tools/url-encoder/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devcove.dev/en/tools/base64/" rel="noopener noreferrer"&gt;https://devcove.dev/en/tools/url-encoder/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I maintain a small toolkit called DevCove for exactly these chores (format, encode, decode in the tab I already have open). curl and server logs still win for reproduction; this is for the moment you're staring at a URL in DevTools and need to know if you're looking at double encoding or a real mismatch.&lt;/p&gt;

&lt;p&gt;Not claiming OAuth is easy. Half our fix was process: register the exact bytes the browser will send, document which encoder each service uses, stop "fixing" URLs by encoding until it looks scary.&lt;/p&gt;

&lt;p&gt;If you've shipped OAuth lately — where do you catch encoding bugs first? Provider logs, proxy logs, or a scratch pad in the browser?&lt;/p&gt;

</description>
      <category>api</category>
      <category>devjournal</category>
      <category>security</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
