1

I am trying to develop a two-tier web application with MarkLogic-9 employing server side JavaScript and HTTP app servers. I have a simple page that prompts for username/password and sends a GET request via Ajax to the app server (application-level authentication).

My login.sjs script:

//generate object with field names from Request params
var params ={}; //JSON parsed URL parameters
var field_names = xdmp.getRequestFieldNames().toArray();
for(var fname_idx in field_names){
  params[field_names[fname_idx]] = String(xdmp.quote(xdmp.getRequestField(String(field_names[fname_idx]))));
}
//get username and password from passed paramters
var username = params.username;
var password = params.password;
var ret = xdmp.login(username,password);

ret;
I have tested this and verified that it works by printing the xdmp.currentUser().

The login page then redirects to a home page that displays basic user info. My problem is that I cannot figure out how to preserve the current user's session after the client-side redirect to the homepage.

The app server has application-level authentication and a default user called Login-User, which is a custom user that has only the privileges necessary to log in (xdmp:login). The app server is hosted on localhost:8601. I have found that when I run login.sjs directly from the browser (i.e. typing localhost:8601/login.sjs?username=test_user&password=test_password), my browser gets a cookie with the sessionID. However, when I run the login.sjs via an Ajax GET request, my browser does not get any cookies. I don't know if this is the issue but I though it might be worth mentioning.

I am still a MarkLogic novice so I may be going about this the completely wrong way. Basically, how do I go about continuing a single user's session after redirecting to a new page? Do I use cookies to save the sessionID? Should I preserve the username and password in local storage and log in every time the website invokes a new .sjs file?

For completeness, here is the client side js I use to make the Ajax call to login. Pretty self-explanatory. The login.sjs file just returns true/false if the login was successful.

function createLoginEar(){
$("#login-button").click(function(event){
    var un = $("#username").val();
    var pw = $("#password").val();
    if(un){
        params.username = $("#username").val();
    }
    if(pw){
        params.password = $("#password").val();
    }
    event.preventDefault(); //prevent form from clearing
    console.log("input entered");
    $.ajax({
        type: "GET",
        url: url,
        data: params,
        success: function(data){
            if(data == "true"){
                console.log("worked");
                window.location.href = "homepage.html";
            } else{
                invalidLogin();
            }
        },
        error: function(data){
            invalidLogin();
        }
    })
})

}

The problem is that once the page redirects to homepage.html, there seems to be no memory of the user having logged in and when homepage.html calls any .sjs file, the user resets to the default which is "Login-User".

Thanks in advance.

Alec Daling
  • 348
  • 2
  • 13

2 Answers2

0

I suggest you look at Chapter 15 of the security guide.

There is a sample of application level authentication using Custom Login Pages.

Lastly, the sample of IP-based login is not what you need, but shows you how to use xdmp.Login to switch users from the default application user.

I think that with all of that covered (not much to it really), you will be able to walk backthrough your setup and re-work it.

  • I apologize if I'm just being dense but I have read through that section and tried everything I can think of but I still can't figure this out. I will try to as something more explicit. After login.html calls login.sjs and successfully logs in, it redirects to homepage.html. When homepage.html calls homepage.sjs (or any other .sjs file on the same app server), it loses track of the fact that the user is logged in and reverts back to the default user (Login-User, in my case). How do I move to another page without losing track of the login? – Alec Daling Jun 11 '17 at 21:32
  • @AlecDaling, the xdmp.login call creates a user session within MarkLogic, and sets a Cookie with the session id. Make sure it is passed through between the page calls. A call with that session id will automatically switch to the appropriate user before invocation.. – grtjn Jun 12 '17 at 07:54
  • Note: also keep in mind that such sessions are tied to specific hosts. If you have a load balancer in between, you need to use sticky sessions.. – grtjn Jun 12 '17 at 07:55
0

The issue was that my browser was not collecting cookies from the login because of issues that are over my head, but I found the answer in another post so this may be a duplicate.

Get and store cookie (from Set-Cookie) from an AJAX POST response.

I just had to include the following line in my ajax request:

xhrFields: { withCredentials: true },

Since this will throw an error if you have a wildcard in you Access-Control-Allow-Origin header, I also had to change this line:

xdmp.addResponseHeader('Access-Control-Allow-Origin', '*');

to this:

xdmp.addResponseHeader('Access-Control-Allow-Origin', 'http://localhost:8010');

And now my browser collects cookies.

Alec Daling
  • 348
  • 2
  • 13