B4J Question jServer Set Session

Chris Guanzon

Active Member
Licensed User
Longtime User
How to set session in jserver?

Is this correct?

B4X:
Sub Handle(req As ServletRequest, resp As ServletResponse)
    req.GetSession.SetAttribute("registered", "some value")
    
    resp.Write("success")
End Sub
 

Chris Guanzon

Active Member
Licensed User
Longtime User
Thanks

But my problem is, when I'm trying to get the session it always gives me a false response.

This is the code I used for getting the session:

B4X:
If req.GetSession.GetAttribute2("registered", "some value") = True Then
    Result = true
Else
    Result = False
End If
 
Upvote 0

Chris Guanzon

Active Member
Licensed User
Longtime User
How about this?

B4X:
Dim registeredvalue As String = req.GetSession.GetAttribute("registered")
If registeredvalue <> "" Then
    Result = true
Else
    Result = False
End If

yes, this will give me a true response. what I want to do is get the value in session not the name.

B4X:
Public Sub Filter(req As ServletRequest, resp As ServletResponse) As Boolean
    Dim AuthorizationHeader As String = req.GetHeader("Authorization")
    Dim Result As Boolean
    
    If AuthorizationHeader.Length > 7 Then
        Dim token As String = AuthorizationHeader.SubString(7).Trim
        Log("Token from Auth-Header: " & token)
        'check token
        If req.GetSession.GetAttribute2("registered", token) = True Then
            'check that no more than 30 minutes passed since last activity
            If req.GetSession.LastAccessedTime + DateTime.TicksPerMinute * 30 > DateTime.Now Then
                resp.Write("Success")
                Result = True 'allow request to continue
            Else
                resp.Write("Session Expired.")
                Result = False
            End If
        Else
            Dim data As List
            data.Initialize
            data.Clear
'            For xx = 0 To 10' Contactz.Size-1
            data.Add(CreateMap("status": 401, "message": "Unathorized."))
'            Next
            JSONGenerator.Initialize2(data)
            Log (JSONGenerator.ToPrettyString(0))
            resp.Write(JSONGenerator.ToPrettyString(1))
            Result = False 'do not allow to continue
        End If
        
    End If
    Return Result
End Sub
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
If req.GetSession.GetAttribute2("registered", token) = True Then
That line does not really make sense to me. To me this says, get the value of "registered", and if not found, return the token (a string) and check if it is True (string <-> boolean).

GetAttribute2 is like Map.GetDefault("key", "ReturnDefaultIfNotFound")

Maybe something like this:
B4X:
Public Sub Filter(req As ServletRequest, resp As ServletResponse) As Boolean
    Dim AuthorizationHeader As String = req.GetHeader("Authorization")
    
    Dim token As String
    If AuthorizationHeader.Length > 7 Then
        token = AuthorizationHeader.SubString(7).Trim
    end if    

     'check token
     If IsTokenAValidOne(token) then ' e.g. check in database if the token is allowed
            ' valid, but check that no more than 30 minutes passed since last activity
            If req.GetSession.LastAccessedTime + DateTime.TicksPerMinute * 30 > DateTime.Now Then
               ' less than 30 minutes
               req.GetSession.SetAttribute("registered", True)
               resp.write("Success")
               return True
            Else
               ' more than 30 minutes
               req.GetSession.SetAttribute("registered", False)
               resp.status = 401
               resp.write("Unauthorized")
               return False
            End Iff
     Else
            ' it isn't valid (e.g. not in database), so we do not even have to check the 30 minutes
            req.GetSession.SetAttribute("registered", False)
            resp.status = 401
            resp.write("Unauthorized")
            return False
     End if
End Sub

In our normal Handlers, we can no check the status for "registered" by using

B4X:
If req.GetAttribute2("registered", False) Then ' get the registered attribute value, and if not found, return False

Else

End if

Alwaysbusy
 
Upvote 0

Chris Guanzon

Active Member
Licensed User
Longtime User
That line does not really make sense to me. To me this says, get the value of "registered", and if not found, return the token (a string) and check if it is True (string <-> boolean).

Hello @alwaysbusy, thank you for your response to my question. I've tried your example above, I can now check the attributes in the session, but after successfully getting the session, I got this error in my client app. Error 404

B4X:
** Activity (main) Resume **
ResponseError. Reason: Not Found, Response: <html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 404 Not Found</title>
</head>
<body><h2>HTTP ERROR 404</h2>
<p>Problem accessing /v1/get. Reason:
<pre>    Not Found</pre></p><hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.z-SNAPSHOT</a><hr/>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 404 Not Found</title>
</head>
<body><h2>HTTP ERROR 404</h2>
<p>Problem accessing /v1/get. Reason:
<pre>    Not Found</pre></p><hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.z-SNAPSHOT</a><hr/>
</body>
</html>

Did I missed something in my code? Please check my code.


B4X:
Public Sub Filter(req As ServletRequest, resp As ServletResponse) As Boolean
    resp.ContentType = "application/json"
    
    Dim AuthorizationHeader As String = req.GetHeader("Authorization")
    Dim Result As Boolean
    Dim token As String
    
    If AuthorizationHeader.Length > 7 Then
        token = AuthorizationHeader.SubString(7).Trim
    End If

    'check token
    If Database.IsTokenAValidOne(token) Then ' e.g. check in database if the token is allowed
        If req.GetSession.GetAttribute2(token, False) = True Then
            ' valid, but check that no more than 30 minutes passed since last activity
            If req.GetSession.LastAccessedTime + DateTime.TicksPerMinute * 30 > DateTime.Now Then
                ' less than 30 minutes
                req.GetSession.SetAttribute(token, True)
                status = 200
                message = "success"
                Result = True
            Else
                ' more than 30 minutes
                req.GetSession.SetAttribute(token, False)
                req.GetSession.RemoveAttribute(token)
                status = 422
                message = "Session timed out."
                Result = False
            End If
        Else
            status = 401
            message = "Unauthorized."
            Result = False
        End If
    Else
        status = 400
        message = "Invalid token."
        Result = False
    End If
    
    Dim ResponseMap As Map
    ResponseMap.Initialize
    ResponseMap.Put("status", status)
    ResponseMap.Put("message", message)
    Variables.jsonGenerator.Initialize(ResponseMap)
    resp.Write(Variables.jsonGenerator.ToString)
    Log(Variables.jsonGenerator.ToString)
    Return Result
End Sub

This is the client code:

B4X:
Dim JSONString As String
    Dim Result As Boolean
    
    Try
        PATH = "xxxx"
        HTTP.Initialize("Job", Me)
        HTTP.PostString($"${URL}${PATH}"$, $"username=user&password=password"$)
        
        Wait For (HTTP) Jobdone (j As HttpJob)
        If j.Success Then
            Dim parser As JSONParser
            JSONString = j.GetString
            parser.Initialize(JSONString)
            Dim root As Map = parser.NextObject
            Dim message As String = root.Get("message")
            Dim status As Int = root.Get("status")
            
            Select Case status
                Case 200
                    Dim strtoken As String = root.Get("token")
                    TOKEN = strtoken
                    MsgboxAsync(message, "")
                    Result = True
                Case 422
                    MsgboxAsync(message, "")
                    Result = False
            End Select
        End If
    Catch
        Log(LastException)
        Result = False
    End Try
    j.Release
 
Upvote 0

MathiasM

Active Member
Licensed User
Are you sure the filter is added to the server for that specific url?

Also, you're not setting the Authorization header in your client code. You're just sending POST parameters.
 
Upvote 0
Top