B4J Question Token authentication coding practice for a JSON/REST API

Paul_

Member
Licensed User
In the past I have made B4J apps that connect to REST API's with XML and basic j.Username/j.Password login before sending a j.PostString or J.GetRequest. Then the XML messages are sent as a simple string.

And I really have to thank OliverA for his help in solving some of my issue in the past, thank you

But now I have to connect to an REST API using a token login that expires after some time and I have no idea what the usual coding practice for a token login and parsing JSON messages should be.

Can anyone offer some friendly advice or code examples?
 

behnam_tr

Active Member
Licensed User
Longtime User
i am using this code and is ok for restapi

B4X:
Sub Send_SMS(msg As String ,tonumber As String)
    
    Dim smsurl As String="https://ippanel.com/api/select"
    Dim token As String = "fi3IVytk8Pdu8r0wQM=654515678578"
    
    Dim objMap As Map
    objMap.Initialize
    objMap.Put("op" , "send")
    objMap.Put("uname","1545140241")
    objMap.Put("pass","155454")
    objMap.Put("message" , msg)
    objMap.Put("from", "454151005")
    objMap.Put("to" , tonumber)
    objMap.Put("time" , "")
    
    Dim objJSon As JSONGenerator
    objJSon.Initialize(objMap)
    
    Dim j As HttpJob
    j.Initialize("j",Me)
    j.PostString(smsurl,objJSon.ToPrettyString(2))
    j.GetRequest.SetContentType("application/json")
    j.GetRequest.SetHeader("authorization",token )
    
    Wait For (j) JobDone(j As HttpJob)
    If j.Success Then
        Log(j.GetString)
        
        Dim parser As JSONParser
        parser.Initialize(j.GetString)
        Dim m As List = parser.NextArray
        Dim state As Int = m.Get(0)
        
        If state<>0 Then
            log("ok")
        End If
        
    Else
        log("error")
    End If
    j.Release
    
    
End Sub
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
I've read it a few times but In my case I'm not connecting to Google
You are not providing enough informations for us to help you. What api exactly you are using? Where is the documentation of this Api?
All we can do is fishing....

Expiring tokens are usually used in a OAuth2-Environment so i pointed to the Tutorial about OAuth2.
 
Upvote 0

Paul_

Member
Licensed User
@DonManfred

You are 100% correct. I have attached the API documentation below.

In principle the process "seems" quite simple, request a Token and then use the Token to login and post the JSON message.

But we all learn from examples and I couldn't find any similar examples on the forum. Is this a very unusual thing to do in B4J?

I could spend hours or days struggling to find the correct B4J method or syntax to make the connection with the API and still fail. I am hopeful some B4X experts will know how to do this?

After making a connection do I need to refresh the token or just request a new token every time I try and post a new message?
 

Attachments

  • API SPEC for Paul.pdf
    23.4 KB · Views: 299
Upvote 0

Paul_

Member
Licensed User
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
This should get you started. Note: it seems like the services api point is not up and running for testing.
B4X:
'Non-UI application (console / server application)
#Region Project Attributes 
    #CommandLineArgs:
    #MergeLibraries: True 
#End Region

Sub Process_Globals
    
End Sub

'Note: use http://basic4ppc.com:51042/json/index.html to parse returned JSON and help with code for accessing information

Sub AppStart (Args() As String)

    
    Log("Hello world!!!")
    testAPI
    StartMessageLoop
End Sub

Sub testAPI
    Wait for(fetchToken) Complete (result As Map)
    If result.IsInitialized Then
        wait for (receiveRCU(result.Get("accessToken"))) complete (success As Boolean)
        Log($"receiveRCU was successful: ${success}"$)
    End If
    StopMessageLoop
End Sub

Sub fetchToken As ResumableSub
    Dim result As Map
    
    Dim jsonMaker As JSONGenerator
    Dim userInfo As Map
    userInfo = CreateMap("UserNameOrEmailAddress":"elecon",  "Password":"1q2w3E*")
    jsonMaker.Initialize(userInfo)
    
    Dim j As HttpJob
    j.Initialize("", Me)
    j.PostString("https://hskpapidev.staypls.com/api/TokenAuth/Authenticate", jsonMaker.ToString)
    j.GetRequest.SetHeader("Abp.TenantId", "1")
    j.GetRequest.SetContentType("application/json")
    Wait For (j) JobDone(j As HttpJob)
    If j.Success Then
        Log(j.GetString)
        'The site is inconsistent in using HTML status codes. It returns error HTML w/200 status code
        Dim error As Boolean = False
        Try
            Dim parser As JSONParser
            parser.Initialize(j.GetString)
            Dim root As Map = parser.NextObject
        Catch
            error = True
        End Try
        If Not(error) Then
            Dim success As String = root.Get("success")
            If success.EqualsIgnoreCase("true") Then
                Dim result As Map = root.Get("result")
                Dim expireInSeconds As Int = result.Get("expireInSeconds")
                Log(expireInSeconds)
                Dim accessToken As String = result.Get("accessToken")
                Log(accessToken)
            End If
        End If
    Else
        Log($"Error: ${j.ErrorMessage}"$)
    End If
    
    Return result
End Sub

Sub receiveRCU(token As String) As ResumableSub
    Dim succesful As Boolean = False
        
    Dim jsonMaker As JSONGenerator
    Dim requestInfo As Map
    requestInfo = CreateMap("RoomNo": "1505", "Attribute": "MUR", "AttributeValue": "1" )
    jsonMaker.Initialize(requestInfo)
    
    Dim j As HttpJob
    j.Initialize("", Me)
    j.PostString("https://hskpapidev.staypls.com/api/services/app/Elecon/RCUTask", jsonMaker.ToString)
    j.GetRequest.SetHeader("Authorization", $"Bearer ${token}"$)
    j.GetRequest.SetContentType("application/json")
    Wait For (j) JobDone(j As HttpJob)
    If j.Success Then
        Log(j.GetString)
        Dim error As Boolean = False
        Try
            Dim parser As JSONParser
            parser.Initialize(j.GetString)
            Dim root As Map = parser.NextObject
        Catch
            error = True
        End Try
        If Not(error) Then
            Dim success As String = root.Get("success")
            If success.EqualsIgnoreCase("true") Then
                succesful = True
            End If
        End If
    Else
        Log($"Error: ${j.ErrorMessage}"$)
    End If
    
    Return succesful
End Sub
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Your overall understanding is correct. The link though actually returns a code of 200 (actual HTTP return code), but shows it as a 404 and has 404 in the link.
 
Upvote 0

mfstuart

Active Member
Licensed User
Longtime User
I tried @OliverA 's code and it worked without any modifications. Thank you both of you.
I'm sure this will come to use in the future for Token Authentication.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…