Creating database entries in Exist-DB with Ajax ca

2019-08-21 07:41发布

问题:

While developing a self-contained exist-db app I ran into some issues with passing on the user's identity during an ajax call.

I have created a standard page that allows the user to login in with his or her standard exist-db account. (It's more or less based on this https://github.com/eXist-db/existdb-login ).

At some point, the users need to create their own entries and upload files, and this is done with an ajax script (I'm using Kartik's bootstrap uploader, but it's basically a standard ajax upload function):

$('#input-24').fileinput({

        uploadUrl: "../modules/uploader.xql",
        uploadAsync: true,

        fileActionSettings : {
            uploadExtraData() {

                return {
                    'FileName': $(this).data('title'),

                }
            }
        },
    });  

Now, of course, this will fail, since it will appear like a GUEST user is trying to create entries, which is an action that is allowed only for registered users.

Does exist-db allow a way to send in my login credentials at this point without having to resort to the standard HTTP login (which is problematic, since it means creating a cookie to memorize the password, which more or less renders the whole login suing exist's mechanisms useless), or is there any way to use the controller instead of an external script?

Thanks in advance!

回答1:

I think you can add the user and password into the URI to trigger the Ajax client to do basic with. e.g. http://username:password@your-server/some/uri/modules/uploader.xql



回答2:

For simple, basic authentication we do the following since the page itself is being served from xQuery.

step 1: we create in the page xQuery a variable containing the session info. This should be fine for you ... the result of your login would be an HTML page:

let $sessinfo := util:base64-encode(concat(request:get-parameter('user', ()), ":", request:get-parameter('pass', ())))

step 2: during the build of the result page in xQuery, we turn that into a javascript variable through a simple script command placed in <head> tag:

<script>
    var sessinfo = "{$sessinfo}";
</script>

step 3: in Javascript loaded with the page (we use jQuery), after the page is ready we setup authentication for all AJAX requests:

jQuery.ajaxSetup({
  headers: {
    "Authorization": "Basic " + sessinfo
  }
});

After that, any AJAX request made would send basic authentication header with user and password to other xQueries executed with jQuery.ajax



回答3:

To have an eXistdb session work with XHR (Ajax requests) you need make sure that

login:set-user('my.login.domain', (), false())

is called in the controller before you forward it to your request handler. Otherwise all request will seem to originate from the 'guest' user.

If you want to use vanilla/native JavaScript requests e.g. fetch you also need to tell it to add the credentials to the request:

fetch(url, { credentials: 'same-origin', method: 'GET' })

By the way, the persistent login used in exidtb-login likely uses a cookie value to pick up the session variables stored on the server (JSESSIONID), but I need to check that.