Users and sessions
REST requests can benefit from web user sessions, providing extra features such as multiple requests handling, data sharing between the web client processes, and user privileges.
As a first step to open a REST session on the 4D server, the user sending the request must be authenticated.
Authenticating users
You log in a user to your application by calling $directory/login
in a POST request including the user's name and password in the header. This request calls the On REST Authentication
database method (if it exists), where you can check the user's credentials (see example below).
Opening sessions
When scalable sessions are enabled (recommended), if the On REST Authentication
database method returns true
, a user session is then automatically opened and you can handle it through the Session
object and the Session API. Subsequent REST requests will reuse the same session cookie.
If the On REST Authentication
database method has not been defined, a guest
session is opened.
Preemptive mode
On 4D Server, REST requests are automatically handled through preemptive processes, even in interpreted mode. You need to make sure that your code is compliant with a preemptive execution.
With 4D single-user, interpreted code always runs in cooperative mode.
Example
In this example, the user enters their email and password in an html page that requests $directory/login
in a POST (it is recommended to use an HTTPS connection to send the html page). The On REST Authentication
database method is called to validate the credentials and to set the session.
The HTML login page:
<html><body bgcolor="#ffffff">
<div id="demo">
<FORM name="myForm">
Email: <INPUT TYPE=TEXT NAME=userId VALUE=""><br/>
Password: <INPUT TYPE=TEXT NAME=password VALUE=""><br/>
<button type="button" onclick="onClick()">
Login
</button>
<div id="authenticationFailed" style="visibility:hidden;">Authentication failed</div>
</FORM>
</div>
<script>
function sendData(data) {
var XHR = new XMLHttpRequest();
XHR.onreadystatechange = function() {
if (this.status == 200) {
window.location = "authenticationOK.shtml";
}
else {
document.getElementById("authenticationFailed").style.visibility = "visible";
}
};
XHR.open('POST', 'http://127.0.0.1:8044/rest/$directory/login'); //rest server address
XHR.setRequestHeader('username-4D', data.userId);
XHR.setRequestHeader('password-4D', data.password);
XHR.setRequestHeader('session-4D-length', data.timeout);
XHR.send();
};
function onClick()
{
sendData({userId:document.forms['myForm'].elements['userId'].value , password:document.forms['myForm'].elements['password'].value , timeout:120})
}
</script></body></html>
When the login page is sent to the server, the On REST Authentication
database method is called:
//On REST Authentication
#DECLARE($userId : Text; $password : Text) -> $Accepted : Boolean
var $sales : cs.SalesPersonsEntity
$Accepted:=False
//A '/rest' URL has been called with headers username-4D and password-4D
If ($userId#"")
$sales:=ds.SalesPersons.query("email = :1"; $userId).first()
If ($sales#Null)
If (Verify password hash($password; $sales.password))
fillSession($sales)
$Accepted:=True
End if
End if
End if
As soon as it has been called and returned
True
, theOn REST Authentication
database method is no longer called in the session.
The fillSession
project method initializes the user session, for example:
#DECLARE($sales : cs.SalesPersonsEntity)
var $info : Object
$info:=New object()
$info.userName:=$sales.firstname+" "+$sales.lastname
Session.setPrivileges($info)
Use (Session.storage)
If (Session.storage.myTop3=Null)
Session.storage.myTop3:=$sales.customers.orderBy("totalPurchase desc").slice(0; 3)
End if
End use