Closed behrad closed 7 years ago
@behrad What error are you getting?
I don't how I should use this @0candy ?! I'm currently using token based User authentication, however tokens need login, and do have TTL. I prefer permanent API keys for my REST clients. How can I integrate this across loopback's default token based authentication.
For now loopback supports token based authentication, but there is a feature request out there to support permanent tokens which I am unable to find at the moment. (Will post when I find it.)
Are you able to make authenticated request with access tokens for now? https://docs.strongloop.com/display/public/LB/Making+authenticated+requests#Makingauthenticatedrequests-Makingauthenticatedrequestswithaccesstokens
@behrad Were you able to get it working?
@behrad Closing due to inactivity. If you are still running into problems, feel free to leave a comment and I will reopen the issue.
I've overridden AccessToken#findForRequest to use Application's one of clientkey, restApiKey, masterKey, ... as a permanent token mechanism, However I'd rather to see this built in loopback core.
@behrad can you please tell me how you implemented that !
i'm facing the same issue trying to authorize some end points using the restApiKey
...
I've a boot script which is overriding AccessToken.findForRequest
@dyaa
note that the dirty part is that I was forced to copy/paste private tokenIdForRequest
inside loopback auth imlementation.
module.exports = function (server) {
var _findForRequest = AccessToken.findForRequest.bind(AccessToken);
AccessToken.findForRequest = function(req, options, cb){
_findForRequest(req, options, function(err, token){
if(!err && !token) { //check if the normal loopback token auth has found the token
var reqToken = tokenIdForRequest(req, options);
if( reqToken ) {
Application
.authenticateKey(reqToken)
.then(token => {
cb && cb(err, token);
})
.catch(err => {
cb && cb(err);
});
return;
}
}
cb && cb(err, token);
});
};
function tokenIdForRequest(req, options) {
var params = options.params || [];
var headers = options.headers || [];
var cookies = options.cookies || [];
var i = 0;
var length;
var id;
// https://github.com/strongloop/loopback/issues/1326
if (options.searchDefaultTokenKeys !== false) {
params = params.concat(['access_token']);
headers = headers.concat(['X-Access-Token', 'authorization']);
cookies = cookies.concat(['access_token', 'authorization']);
}
for (length = params.length; i < length; i++) {
var param = params[i];
// replacement for deprecated req.param()
id = req.params && req.params[param] !== undefined ? req.params[param] :
req.body && req.body[param] !== undefined ? req.body[param] :
req.query && req.query[param] !== undefined ? req.query[param] :
undefined;
if (typeof id === 'string') {
return id;
}
}
for (i = 0, length = headers.length; i < length; i++) {
id = req.header(headers[i]);
if (typeof id === 'string') {
// Add support for oAuth 2.0 bearer token
// http://tools.ietf.org/html/rfc6750
if (id.indexOf('Bearer ') === 0) {
id = id.substring(7);
// Decode from base64
var buf = new Buffer(id, 'base64');
id = buf.toString('utf8');
} else if (/^Basic /i.test(id)) {
id = id.substring(6);
id = (new Buffer(id, 'base64')).toString('utf8');
// The spec says the string is user:pass, so if we see both parts
// we will assume the longer of the two is the token, so we will
// extract "a2b2c3" from:
// "a2b2c3"
// "a2b2c3:" (curl http://a2b2c3@localhost:3000/)
// "token:a2b2c3" (curl http://token:a2b2c3@localhost:3000/)
// ":a2b2c3"
var parts = /^([^:]*):(.*)$/.exec(id);
if (parts) {
id = parts[2].length > parts[1].length ? parts[2] : parts[1];
}
}
return id;
}
}
if (req.signedCookies) {
for (i = 0, length = cookies.length; i < length; i++) {
id = req.signedCookies[cookies[i]];
if (typeof id === 'string') {
return id;
}
}
}
return null;
}
}
I think if you simply want to protect some REST paths with permanent keys, you could register a custom middleware for the auth-phase. ... you will run into problems when combining this middleware with other authentication methods for the same rest points.
The middleware would check for a http header:
var apiKey = req.headers["x-api-key"];
If the key is not valid, you'd return the res object with
res.status(401).send('Missing/Bad API Key');
If you create the middleware, How can I show this in the loopback-component-explorer?. To use it in the documentation of REST API. Same as the token section to put the token and set the access token for all operations.
I couldn't be able to create a working example and use generated
restApiKey
in my application instance to secure and call REST endpoints.