Basic Auth authentication help to a newbie

494 views
Skip to first unread message

X orko

unread,
Dec 10, 2016, 10:59:24 AM12/10/16
to Keystone JS
Hi guys,

I am new to both Keystone JS and Node.js and I am having trouble understanding how I can authenticate with basic auth on my route endpoints.
Currently all my calls get redirected to signin unless I login to the backend and create a session.

My layout is as follows: 

Basic project created with generator-keystone in yeoman. 
I did not add the blog feature, so it is pretty barebone.

I have added custom models and api routes (they work, but I must be logged in to use them).
In keystone/public I have added my Angular JS 1.x frontend which is supposed to do the api calls.

The following is the request header in my Angular app: 
var requestObj = {
url: 'http://localhost:3000/keystone/api',
usr: 'us...@email.com',
pass: 'password',
withCredentials: true,
method: 'POST'
};

requestObj.auth = window.btoa(requestObj.usr + ':' + requestObj.pass);
requestObj.headers = {"Authorization": "Basic " + requestObj.auth};

var data = _handleRequest(requestObj);

_handleRequest looks like the following: 
var _handleRequest = function(requestObj) {
    var data = {};

    if(requestObj.method === undefined) {
        requestObj.method = 'GET';
    }

    return $http(requestObj, {headers: $keystoneApi.headers})
        .then(
            function success(response) {
                return response.data;
            },
            function error(response) {
                // todo; handle error
                $log.info(response);
            }
        );
};

Could anyone please guide me in the right direction? 

I feel like there is probably something essential and possibly simple that I am missing. 

With the exception from adding routes and models I have not done anything else to alter my keystone installation.


Jeffrey Priebe

unread,
Dec 10, 2016, 1:52:07 PM12/10/16
to Keystone JS
Keystone is setup to do logins via the form. You are trying to do send the credentials via the basic authorization header. That's a different mechanism and keystone doesn't "just read" that information.

In node (really, in Express which Keystone uses and Express is what handles the routes, etc.) the common way to handle this is via middleware.
So, at least on these routes (in express you configure middleware at whatever level you want: per single route, a whole group, or all), you'd want middleware that handled the basic authorization and then proceeded to talk to the keystone authorization.

There are some packages for basic auth for express on npm, though nothing looks incredibly popular/well used.
https://www.npmjs.com/package/express-basic-auth

Keystone signin api likely is most instructive as it calls a user pre:signin hook and handles the sign in: https://github.com/keystonejs/keystone/blob/master/admin/server/api/session/signin.js

Hopefully that gets you heading in the right direction.


X orko

unread,
Dec 10, 2016, 2:16:56 PM12/10/16
to Keystone JS
Aha! That is great information! 
I was wondering since I also saw that the default signin did not use any action on the form. 

Thank you also for the examples, I will look into them and see which solution I will go for ;)

Chris Troutner

unread,
Dec 10, 2016, 5:50:36 PM12/10/16
to Keystone JS
You could check out the code in the ConnextCMS repo for KeystoneJS API examples that use authorization.

I'm working on updates to security updates. The master branch doesn't have these security updates but the unstable branch does.

You can check out tje file /routes/api/posts.js file for an example. Hopefully this link works

The code allows public access to list and get API calls. The user is authenticated in update, create, and remove API calls, using this code:

//Ensure the user has a valid CSRF token
if (!security.csrf.validate(req)) {
 
return res.apiError(403, 'invalid csrf');
}


//Ensure the user making the request is a Keystone Admin
var isAdmin = req.user.get('isAdmin');
if(!isAdmin) {
return res.apiError(403, 'Not allowed to access this API. Not Keystone Admin.');
}


//Since it's possible to spoof the Keystone Admin setting in the current version of the User model,
//This is a check to make sure the user is a ConnexstCMS Admin
var admins = keystone.get('admins');
var userId = req.user.get('id');
if(admins.indexOf(userId) == -1) {
return res.apiError(403, 'Not allowed to access this API. Not ConnextCMS Admin')
}


The first paragraph validates a CSRF token. The second paragraph ensure the user is a Keystone Admin. 

The third paragraph is specific to ConnextCMS. I'm in the processes of changing some of the default KeystoneJS security features.
Reply all
Reply to author
Forward
0 new messages