Removing hash from URL on HTTP redirect

Mik*_*ike 6 url http facebook-graph-api

I just added a feature on a website to allow users to log in with Facebook. As part of the authentication workflow Facebook forwards the user to a callback URL on my site such as below.

https://127.0.0.1?facebook-login-callback?code.....#_=_

Note the trailing #_=_ (which is not part of the authentication data, Facebook appears to add this for no clear reason)

Upon receiving the request in the backend I validate the credentials, create a session for the user, then forward them to the main site using a Location header in the HTTP response.

I've inspected the HTTP response via my browser developer tools and confirmed I have set the location header as.

Location: https://127.0.0.1/

The issue is that the URL that appears in the browser address bar after forwarding is https://127.0.0.1/#_=_

I don't want the user to see this trailing string. How can I ensure it is removed when redirecting the user to a new URL?

The issue happens in all browsers I have tested. Chrome, Firefox, Safari and a few others

I know a similar question has been answered in other threads however there is no jquery or javascript in this workflow as in the other threads. All the processing of the login callback happens in backend code exlusively.

EDIT

Adding a bounty. This has been driving up the wall for some time. I have no explanation and don't even have a guess as to what's going on. So I'm going to share some of my hard earned Stackbux with whoever can help me.

Just To be clear on a few points

  • There is no Javascript in this authentication workflow whatsoever
  • I have implemented my own Facebook login workflow without using their Javascript libraries or other third party tools, it directly interacts with the Facebook REST API using my own Python code in the backend exclusively.

Below are excerpts from the raw HTTP requests as obtained from Firefox inspect console.

1 User connects to mike.local/facebook-login and is forwarded to Facebook's authentication page

HTTP/1.1 302 Found
Server: nginx/1.19.0
Date: Sun, 28 Nov 2021 10:44:30 GMT
Content-Type: text/plain; charset="UTF-8"
Content-Length: 0
Connection: keep-alive
Location: https://www.facebook.com/v12.0/dialog/oauth?client_id=XXX&redirect_uri=https%3A%2F%2Fmike.local%2Ffacebook-login-callback&state=XXXX
Run Code Online (Sandbox Code Playgroud)

2 User accepts and Facebook redirects them to mike.local/facebook-login-callback

HTTP/3 302 Found
location: https://mike.local/facebook-login-callback?code=XXX&state=XXX#_=_
Run Code Online (Sandbox Code Playgroud)

... Requested truncated here. Note the offending #_=_ in the tail of the Location

3后端处理 Facebook 通过用户转发提供的令牌,并为用户创建会话,然后将其转发到mike.local。我没有添加#_=_LocationHTTP 标头,如下所示。

HTTP/1.1 302 Found
Server: nginx/1.19.0
Date: Sun, 28 Nov 2021 10:44:31 GMT
Content-Type: text/plain; charset="UTF-8"
Content-Length: 0
Connection: keep-alive
Location: https://mike.local/
Set-Cookie: s=XXX; Path=/; Expires=Fri, 01 Jan 2038 00:00:00 GMT; SameSite=None; Secure;
Set-Cookie: p=XXX; Path=/; Expires=Fri, 01 Jan 2038 00:00:00 GMT; SameSite=Strict; Secure;
Run Code Online (Sandbox Code Playgroud)

4用户到达并看到URL 中的mike.local尾随。#_=_我在 Firefox、Chrome、Safari 和 Edge 中观察到了这一点。

URL末尾的神秘字符

我已通过 Firefox 检查控制台确认没有发送其他 HTTP 请求。换句话说,我可以确认3是从我的站点发送给用户的最终 HTTP 响应。

use*_*170 9

根据RFC 7231 \xc2\xa77.1.2

\n
\n

如果 3xx(重定向)响应中提供的位置值不包含片段组件,则用户代理必须处理重定向,就像该值继承用于生成请求目标的 URI 引用的片段组件一样(即重定向继承原始引用的片段(如果有)。

\n
\n

如果 Facebook 将您重定向到带有片段标识符的 URI,则该片段标识符将附加到的重定向目标。(我不太同意这种设计;对于 HTTP 303 重定向来说,语义上有意义,这在逻辑上更适合此工作流程,忽略发起者的片段标识符。不过,事实就是如此。)

\n

您能做的最好的事情就是使用目标页面上的 JavaScript 代码片段清理片段标识符:

\n
<script async defer type="text/javascript">\n    if (location.hash === \'#_=_\') {\n        if (typeof history !== \'undefined\' &&\n            history.replaceState &&\n            typeof URL !== \'undefined\')\n        {\n            var u = new URL(location);\n            u.hash = \'\';\n            history.replaceState(null, \'\', u);\n        } else {\n            location.hash = \'\';\n        }\n    }\n</script>\n
Run Code Online (Sandbox Code Playgroud)\n

或者,您可以使用元刷新/ RefreshHTTP 标头,因为该重定向方法不保留片段标识符:

\n
<meta http-equiv="Refresh" content="0; url=/">\n
Run Code Online (Sandbox Code Playgroud)\n

为了不实现Refresh.

\n

但如果你问我\xe2\x80\x99d个人做什么:别管这个可怜的东西。无论如何,无用的片段标识符是相当无害的,并且这种愚蠢的微观管理不值得将整个互联网标准颠倒过来(使用更脆弱的非标准重定向方法;将另一段多余的 JavaScript 推给用户\xe2\x80\x99s 方式)只是为了相当小的地址栏美观。正如《上帝之家》所说:\xe2\x80\x98提供良好的医疗服务就是尽可能不采取任何行动\xe2\x80\x99。

\n