I am trying to create a NodeJS API system for an electron-based desktop application. The app should allow basic login using username and password, after the user logs in, all subsequent API calls are authenticated via ids and secret keys. I am referencing this guide on using express-strompath description here. I am unable to perform username/password authentication like this.
curl -L -H "Content-Type: application/json" -X POST -d '{"password":"Som3Pa55Word", "username":"[email protected]"}' http://ec2-54-88-168-7.compute-1.amazonaws.com:8000/api/v1.0/login
Or via javascript
function Login() {
...
var user = {
username: '[email protected]',
password: 'Som3Pa55Word ',
}
var req = {
method: 'POST',
url: apiBaseUrl + '/login',
headers: {
'Content-Type': 'application/json'
},
data: user
}
return $http(req).then(handleSuccess, handleError);
}
However, when I user the API Key, I am able to log in.
curl -L -H "Content-Type: application/json" -X POST --user ABCDEFGHIJKLMNOPQRSTUVWXYZ:AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz -d '{}' http://ec2-54-88-168-7.compute-1.amazonaws.com:8000/api/v1.0/login
Or via javascript
var url = apiBaseUrl + '/login';
var sp_api_key_id = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var sp_api_key_secret ='AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz';
get the Resource object w/ custom "get" method
$resource(url, {}, {
get: {
method: 'GET',
headers: {
Authorization: 'Basic ' +
$base64.encode(sp_api_key_id + ':' + sp_api_key_secret)
}
}
}).get().then(function(result) {
console.log("Loging Success")
});
Obviously it's inconvenient to have users enter their API keys into a form for authentication. I was wondering why stormpath-express accepts API ID/Secret combinations but not username/password.
Here is the code for my nodejs server
router.post('/login', stormpath.loginRequired, function (req, res, next) {
/*
* If we get here, the user is logged in. Otherwise, they
* were redirected to the login page
*/
var respnse = {
message: 'If you can see this page, you must be logged into your account!'
}
res.json(respnse);
res.status(200);
});
And Stormpath setup code
// Config
app.use(stormpath.init(app, {
// TODO
// apiKeyFile: './app/config/stormpath_apikey.properties',
application: 'https://api.stormpath.com/v1/applications/ABCDEFGHIJKLMNOPQRSTUVWXYZ',
secretKey: settings.stormpath_secret_key,
web: {
login: {
enabled: false
},
register: {
uri: '/user/register'
},
preLoginHandler: function (formData, req, res, next) {
console.log('Got login request', formData);
next();
}
},
postLoginHandler: function (account, req, res, next) {
console.log('User:', account.email, 'just logged in!');
next();
}
}));
I work at Stormpath. The API Key authentication feature, where accounts are issued API keys, is meant to be used for server-to-server clients, not web browser clients. As such, API Keys are meant to be used with HTTP Basic Authentication or to be exchanged for OAuth2 access tokens. Both of those strategies are described in this documentation:
http://docs.stormpath.com/nodejs/express/latest/authentication.html#http-basic-authentication
http://docs.stormpath.com/nodejs/express/latest/authentication.html#oauth2-client-credentials
Web browser clients are meant to use the
/login
endpoint, and they receive an Oauth2 access and refresh token in response (we store these in secure cookies). This is a special nuance of express-stormpath. You can do a proper OAuth2 password exchange by using the oauth/token endpoint, that is also described here:http://docs.stormpath.com/nodejs/express/latest/authentication.html#oauth2-password-grant
I hope this answer helps!