Modx User Login From Vue.js App

Hello everyone,
Is there any documentation explaining how to properly connect to MODX from a remote application (Vue, React, etc.)?

I’m currently working on a project using Vue.js (with Nuxt.js).
Currently, everything is built in the classic way (chunk, snippet, etc.) and works in the classic way.
Now, I want to redo the app with Vue JS and Vuetify, which makes it possible to do something really professional and classy.

With Axios, I’m able to interact with MODX, and retrieve and display information from modx with Vuetify: it’s perfect! Everything works perfectly.

The only problem is this:

I’m now running into a problem with authentication. In fact, some of the resources are private, and the display is conditioned according to the user group to which the user belongs.
And I don’t know how to manage authentication reliably and efficiently from Vue. I do have a [login / password] form, but is it possible to use the Login extension from the outside to retrieve the user’s info?

I can’t find any examples or documentation on the subject, and I don’t even know if it’s possible. And if it is possible, what’s the right way to do it?
Is there any documentation explaining how to properly connect to MODX from a remote application (Vue, React, etc.)?

(Ultimately, the application will be hosted on the same server, in a MODX folder. But development is done locally).

thank you in advance for all your info on the subject.

The Login extra uses the MODX processor security/login to log in a user.

I guess if you have the [[!Login]] snippet on a page, you could make an AJAX request to this page (with the parameters for “user” and “password”) and the user should get logged in.

A cleaner solution is probably to create a REST endpoint for the login and call the security/login processor yourself:

But it doesn’t seem that you created a rest API on your site.
How do you handle AJAX requests to your site? With normal MODX resources that return JSON?

1 Like

Yes, that’s exactly it.

Currently, I have a modx resource, containing a “VueServices” snippet.
From the Vue application, I call this resource with parameters.
The snippet retrieves the information passed in $_GET and returns JSON.
It works fine, but I’m not sure it’s the best method…

The “best” method always depends on the use case.

If you have a lot of different endpoints, I would recommend the extra QuickApi. It basically does the same (executes a snippet on a resource and returns JSON) but it simplifies things.

Here is a video on how to use it.


You could also create a RESTful API, but this approach has different drawbacks. (For example if you return the content of a resource, the tags don’t get automatically parsed by the MODX parser. So you have to execute the parser yourself.)

1 Like

Thank you so much for this information halftrainedharry, I will look and try this.

Hi there, I usually work with Vite+Vue+MODX. Here is an example of the standard login I use in most of my projects. It has some particular stuff related to the routing of this particular one based on the user group, but I’ll give you an idea.

Also, I’m developing an extra to integrate Vue and MODX. It basically integrates the parser along the Vue build to allow MODX tags along the Vue ones , this particular version has Quasar preconfigured.

In case its of use, I normally work with this container it already has all the needed dependencies as well as some things I like using to develop, like gitify and GPM to actually build and package my projects

Finally, here is and old video about the extra

1 Like

I’ve done this quite a bit with Modx and it is relatively straightforward using the Modx Processor. Typically I’ll do this through a REST framework however it shouldn’t be to difficult to add to a snippet and call on a resource. As an example here is an edited version which might work as a snippet:

<?php

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $ctx = $modx->getOption('context', $_POST, 'web');

    $headers = getallheaders();

    $response = [
        'code' => 200,
        'message' => 'Logged in'
    ];
    
    // Check if the user has an active session on this context
    if (!$modx->user->hasSessionContext($ctx)) {
        // Check for username in header
        if (!is_null($headers['php-auth-user'])) {
            // log the user in
            $data = array(
                'username' => $headers['php-auth-user'],
                'password' => $headers['php-auth-pw'],
                'rememberme' => 1,
                'login_context' => $ctx
            );
            $login = $modx->runProcessor('/security/login', $data);
            if ($login->isError()) {
                $response = [
                    'code' => 403,
                    'message' => $response->getMessage()
                ];
            }
        } else {
            $response = [
                'code' => 403,
                'message' => 'Unauthorised'
            ];
        }
    }
} else {
    $response = [
        'code' => 405,
        'message' => 'Method not allowed'
    ];
}

http_response_code($response['code']);

return json_encode($response);

I’ve not tested this snippet as its an edited version that I use with Symfony. You will need to add the following to your .htaccess to allow basic PHP auth.

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

Then you should be able to include the authentication in your fetch request with something like:

let username = document.getElementById('username').value;
let password = document.getElementById('password').value;

let headers = new Headers();
headers.set('Authorization', 'Basic ' + base64.encode(username + ":" + password));

fetch(
    url, 
    {
        method:'POST',
        headers: headers,
    })
    .then(response => response.json())
    .then(json => console.log(json));

Hope that sort of helps