1

I have an application that works as the following:

  • index.html loads index.js
  • index.js looks for a token on local storage, doesn't find it and redirects to auth.php using window.location.href = "auth.php";
  • auth.php redirects to external-api.com using header("Location: external-api.com/login");
  • the user logs in on their platform, which redirects back to auth.php with a code using get request
  • auth.php then makes a post to external-api.com with that code and a few more params, and receives a response with an actual access token
  • auth.php redirects back to index.html using header("Location: index.html?token=".$token);

However, is there a way to redirect back passing data without using query parameters?

TylerH
  • 20,799
  • 66
  • 75
  • 101
James
  • 1
  • 6
  • 4
    If the user knew what to do with such a token, they'd also be able to discover it in the local storage or in requests in the network inspector. It's really mostly a cosmetic problem, not a security issue. I'd remove the query parameter from the URL via Javascript just for cosmetic reasons… – deceze May 24 '23 at 14:41
  • Why are you explicitly putting the token on the URL if the page you're about to load already looks in local storage for the token? Just put the token in local storage and then redirect with a clean URL. – Alex Howansky May 24 '23 at 14:43
  • 2
    *"making the application more secure?"* - How so? What security problem are you trying to correct? Is your position that the user doesn't **need** this token? If so then what happens when you simply don't include it when redirecting from `auth.php`? (The auth flow described implies to me that the user does indeed need this token. So trying to keep them from having it could be problematic. But I may be missing some other information about your application, its authentication/authorization, etc.) – David May 24 '23 at 14:44
  • @AlexHowansky The server has no access to the client's local storage. – Barmar May 24 '23 at 14:48
  • Don't put the token in local storage, put it in a session variable on the server. – Barmar May 24 '23 at 14:48
  • 1
    You might want to look at how the OAuth2 protocol is used in applications like this. – Barmar May 24 '23 at 14:49
  • @David The user does need the token, indeed, however I don't want to expose them to it directly (in the URL). – James May 24 '23 at 14:50
  • 1
    @James: Then this has nothing to do with security. You're essentially just asking how to provide a value to the client without putting it on the URL in a redirect. Perhaps set the token in a cookie instead? Or keep it in session state and the client-side code can make an AJAX request to fetch it? – David May 24 '23 at 14:51
  • 3
    Why do you care if the token is in the URL or not? As David says, it has nothing to do with security. If you're exposing the token to the user / client-side application, then it doesn't really matter how that's done - the data is still there if the user wants to look for it. And if they need it, then they need it, so you can't improve security by not providing it. I would agree with an earlier comment - take a look at how established protocols like OAuth2 do this sort of thing. Or...just make your application compliant with that protocol, rather than re-inventing a similar process. – ADyson May 24 '23 at 14:52
  • @Barmar Certainly. What I mean is, the browser request that calls the page that gets the token from the remote server can be done as an AJAX hit, and take the resulting token, and drop it into local storage directly. – Alex Howansky May 24 '23 at 14:53
  • 1
    @AlexHowansky That may not be possible due to CORS. – Barmar May 24 '23 at 14:58
  • 2
    However it's not a security issue, I think it's an interesting question: How can you pass server-side generated data to Javascript via a get request without using the query parameters? I would say to put it in a cookie. – Remco K. May 24 '23 at 14:59
  • @RemcoK. possibly true. If the OP were to re-word this to just ask about such methods, rather than trying to make it (spuriously) about security, then it might make for a more useful question. – ADyson May 24 '23 at 15:00
  • 2
    Thanks for the update, but ... `How can I redirect back passing data in a way that the user doesn't get access to the token`...you can't. We already explained this. If the token is available in the client-side, then the user can get to it. You can make the process of the user retrieving the token a bit more time-consuming by using some of the methods suggested already, but you can't actually prevent it. And it's still unclear why you care whether the user can see it (in the URL) or not? They need the token for the page to work, so what's the problem with putting it in the URL? – ADyson May 24 '23 at 15:06
  • 1
    You've attempted to re-word the post I see, but the focus is still on the "hiding" issue (which we've explained doesn't really make much sense), rather than looking dispassionately at the technical alternatives for transmitting data to the client-side without using URL parameters, as Remco suggested. – ADyson May 24 '23 at 15:08
  • Instead of an HTTP redirect, auth.php could respond with a document that contains a bit of JavaScript - that stores the token into localStorage first (you are _reading_ it from there, so that's where it needs to end up anyway), and then redirects back to the index, also via JS. – CBroe May 25 '23 at 06:58

1 Answers1

2

Your question is a little unclear because you mention token multiple times, but there are 2 different tokens + a 'code'.

  1. Local storage token
  2. external-api sends user to auth.php?code=some_code
  3. auth.php sends POST request to external-api & gets ACCESS TOKEN

I doubt you can hide the code in step 2 (would depend on how the external API works) & you can't hide the token in step 1 (because it is in local storage, on the client machine). So, I assume you're trying to hide the ACCESS TOKEN received from the POST request to external-api, when redirecting back to index.html

So, assuming the only place you need to hide the token is during header("Location: index.html?token=".$token);, then you can use $_SESSION['token'] = $token, then just use header("Location: index.html); and retrieve $_SESSION['token'] during the request to index.html

Also, you could map the ACCESS TOKEN to an internal code, & pass the internal code to the user. That way, the user could not directly request user information from external-api.

You might be interested in PHP Redirect with POST data, where I further detail the $_SESSION approach.

Reed
  • 14,703
  • 8
  • 66
  • 110
  • 1
    Thank you for your answer! The code in step 2 is a middle step in the way of getting an Access Token. The local storage token I mention is also the Access Token, in which I save it on storage for later use. However, as everybody mentioned, it would be exposed to the user anyway. It'd be better to store it in a session variable as you showed me (or in a DB). However, to retrieve it afterwards by JS, I would have the same problem, so I shouldn't even be handling the token in my frontend in the first place. That's a matter that concerns solely to the backend. Thank you for your contribution! – James May 24 '23 at 19:01