1

I have a Node.js back end that I am using for authentication and for reverse proxy of an ArangoDB Web Interface. I cannot for the life of me figure out why I am unable to log into the Web Interface using my external URL.

I have searched high and low (google, stack overflow, arangodb git issues threads, arangodb app code, etc.), and cannot figure it out. I am not beholden to the node-http-proxy module I am using below. If someone has done this inside of node another way.

I have seen examples using nginx, etc. but I am really trying to keep everything under the node back end to be able to keep the proxy access behind my site authentication so I don't expose the Web Interface to random access.

I am hoping someone who has cleared this hurdle can help.

Issue: The _open/auth request is never responded to. I can still access http://localhost:8529 from the server and login in just fine.

Desired outcome: Access web interface from http://example.com:8080/_db/_system/_admin/aardvark/index.html#login and successfully login.

[Chrome Headers Network Details]:

Request URL: http://example.com:8080/_db/_system/_open/auth
Referrer Policy: no-referrer-when-downgrade

Request Headers:
Provisional headers are shown
Accept: application/json, text/javascript, */*; q=0.01
Authorization: bearer null
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://example.com:8080
Referer: http://example.com:8080/_db/_system/_admin/aardvark/index.html
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
X-Requested-With: XMLHttpRequest

Form Data:
{"username":"username","password":"password"}: 

Interestingly: http://127.0.0.1:8080/_db/_system/_admin/aardvark/foxxes/fishbowl always come up with a 401 error (even on the server on the localhost address and port, think it's a bug with aardvark.js)

See below configuration files.

[routes.js]:

// =====================================
// ArangoDB Web interface ============
// =====================================
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({followRedirects: true});

// set headers location overwrite per arangodb documentation
proxy.on('proxyReq', function(proxyReq, req, res, options) { 
    proxyReq.setHeader('X-Script-Name', 'http://example.com:8080');
});

proxy.on('error', function(e) {
    console.log(e);
});

app.all('*/_db/*', function(req, res) {
    proxy.web(req, res, {target: 'http://localhost:8529'});
});

[/etc/arangodb3/arangod.conf]:

[frontend]
proxy-request-check=false
version-check=false
[http]
trusted-origin=all
allow-method-override=true

Note: I have also tried 'trusted-origin=*' (Not sure which one is correct)

1 Answer 1

1

Solved

Hopefully this helps someone else out!!!

I completely missed the fact that you have to manually pass forward post data from forms to the proxy (thought it would do this automatically). Plus node/arango did something weird when you fetched the post body and append a :"" to the end of the value. So you have to manually remove it.

// =====================================
// ArangoDB query interface Route ========
// =====================================
// Add the following to the arangodb config file /etc/arangodb3/arangodb.conf
// [frontend]
// proxy-request-check = false
// [http]
// trusted-origin = *
// trusted-origin = all

// Create the proxy
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer();

// Catch requests, massage the login form json, and pass along to the proxied server
proxy.on('proxyReq', function(proxyReq, req, res, options) {
    var bodyData;
    var contentType = proxyReq.getHeader('Content-Type');

    if (!req.body || !Object.keys(req.body).length) {
        return;
    };
    if (contentType == 'application/json; charset=UTF-8' || contentType == 'application/json') {
        bodyData = JSON.stringify(req.body);
    };

    if (contentType == 'application/x-www-form-urlencoded; charset=UTF-8' || contentType == 'application/x-www-form-urlencoded') {
        bodyData = queryString.stringify(req.body);
    };

    // handle formatting issue with arangodb web form where it appends a :"" to the end of the credentials (i.e. {"username","root","password","password"}:"")
    if (bodyData) {
        if (req.url.substr(-23) == '/_db/_system/_open/auth') {
            proxyReq.write(String(Object.keys(req.body)[0]))
        } else {
            proxyReq.write(bodyData);
            proxyReq.end();
        };
    };
});

  proxy.on('error', function(e) {
      console.log(e);
  });

  // note I have two functions to ensure that a user is logged in and has a specific role before they can login to the database. Insert authentication functions / middleware before the function(req, res) below
  app.all('*/_db/*', function(req, res) { //, isLoggedIn, inRole('admin')
      proxy.web(req, res, {target: 'http://127.0.0.1:8529'});
  });
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.