B4J Question Get URI fragment portion

Blueforcer

Well-Known Member
Licensed User
Longtime User
im trying to create a authentication flow for Twich.

i started a server wich listens to the callback url, wich already works, but im unable to get the token.

the important part of the documentation:

B4X:
If the user authorizes your application by clicking Authorize, the server sends the access token to your redirect URI in the fragment portion of the URI (see the access_token parameter):

http://localhost:3000/
    #access_token=73d0f8mkabpbmjp921asv2jaidwxn
    &scope=channel%3Amanage%3Apolls+channel%3Aread%3Apolls
    &state=c3ab8aa609ea11e793ae92361f002671
    &token_type=bearer

NOTE In JavaScript, you can access the fragment using document.location.hash.

How can i get the token?

i also tried to open the authorization page in a webview instead of the local browser, but here i also dont get the token.
 

aeric

Expert
Licensed User
Longtime User
B4X:
Dim url As String = $"http://localhost:3000/
#access_token=73d0f8mkabpbmjp921asv2jaidwxn
&scope=channel%3Amanage%3Apolls+channel%3Aread%3Apolls
&state=c3ab8aa609ea11e793ae92361f002671
&token_type=bearer"$
Dim access_token As String = url.SubString2(url.IndexOf("#access_token="), url.IndexOf("&")).Trim.Replace("#access_token=", "")
Log(access_token)
 
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
B4X:
Dim url As String = $"http://localhost:3000/
#access_token=73d0f8mkabpbmjp921asv2jaidwxn
&scope=channel%3Amanage%3Apolls+channel%3Aread%3Apolls
&state=c3ab8aa609ea11e793ae92361f002671
&token_type=bearer"$
Dim access_token As String = url.SubString2(url.IndexOf("#access_token="), url.IndexOf("&")).Trim.Replace("#access_token=", "")
Log(access_token)

Not really. I need to get the token from the response URl wich isnt directly visible in the URI
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
I may be wrong but I don't believe anything after # actually gets sent to the server.

In your example url
All the server sees is

You will need to add some javascript to get it sent to server
you need to send document.location.href like
B4X:
Sub Handle(req As ServletRequest, resp As ServletResponse)
    Log("in test")
    Log(req.GetParameter("from"))
    resp.Write($"<html><form action="/login" method="post">
  <div>
    <label>Username:</label>
    <input type="text" name="username"/><br/>
  </div>
  <div>
    <label>Password:</label>
    <input type="password" name="password"/>
  </div>
  <!-- XXXXXXXXX CLEVER BIT XXXXXXXXXX-->
  <script>
    document.write('<input type="hidden" name="from" value="'+document.location.href+'"/>');
  </script>
  <!-- XXXXXXXXXX-->
  <div>
    <input class="submit-button" type="submit" value="Submit"/>
  </div>
</form></html>"$)
   
End Sub

you can then use
B4X:
req.GetParameter("from")
which gives you

and get the #access_token from that string

Original code posted on SO https://stackoverflow.com/questions/8033537/getting-hash-parameters-from-request-url
 
Last edited:
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
Thanks for the Hint. This is working:

B4X:
Sub server_Handle (req As ServletRequest, resp As ServletResponse)
    If req.GetRequestURI = "/token" Then
        Dim accessToken As String = req.ParameterMap.Get("access_token")
        Log(accessToken)
    Else
        resp.SendString($"<!DOCTYPE html>
            <html>
            <body>
            <script>
            if(window.location.hash) {
                const hash = window.location.hash.substring(1);
                const params = new URLSearchParams(hash);
                const accessToken = params.get('access_token');
                fetch('http://localhost:3000/token?access_token=' + accessToken);
            }
            </script>
            </body>
            </html>"$)
    End If
End Sub
 
Upvote 0
Top