We wanted to make it easier to work with escher requests.
This package provides an alternative to using packages like escher-suiteapi-js
, escher-auth
, escher-keypool
and koa-escher-auth
.
For escher-request
to work, you should set ESCHER_INTEGRATIONS
environment
variable set with all your escher related config.
For compatibility reasons ESCHER_KEY_POOL
and SUITE_ESCHER_KEY_POOL
variables are also supported
for storing config.
process.env.ESCHER_INTEGRATIONS = `[
{
"keyId": "test_test-sender_v1",
"secret": "code"
}
{
"keyId": "test_test-target_v1",
"secret": "secret",
"serviceUrl": "http://www.example.com:8080",
"credentialScope": "eu/test-target/ems_request"
}
]`;
For each service you want to communicate with include an object in the array with these params:
keyId
sent with outgoing request, used during authentication to look up the matching secretsecret
used to generate and validate the signatureserviceUrl
(optional) base url of the service (needed for outgoing requests)credentialScope
(optional) will be set in auth header when sending a request towards the service (needed for outgoing requests)acceptOnly
(optional, defaultfalse
) makes it easier to rotate your keys. When it'strue
it will only be used to validate incoming requests, and you can have a second entry for this service with the newsecret
, version two (..._v2
) key id andacceptOnly
asfalse
which will be used for outgoing ones.
Request API is intended to be as close to axios API as possible.
// Send a POST request
escherRequest.request({
method: 'post',
url: 'http://somewhere.com/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
})
The main difference is that only absolute url work, as the origin part of the url will be used
to look up the escher keyId
and secret
set up in ESCHER_INTEGRATIONS
for signing the request.
There is also an extra escherKeyId
option, which lets you make calls with relative urls.
In this case this keyId
will be used to look up the serviceUrl
of the target which will
be prepended to the url.
escherRequest.get('/hello', { escherKeyId: 'test_test-target' })
Omit version information from the end of the key for this config (eg: key
instead of key_v1
)).
This allows you to write environment independent code more easily.
You only have to change the value of the ESCHER_INTEGRATIONS
environment variable
between environments, and your requests will go to the correct destination signed with
the correct credentials.
If you would like to use the package without ESCHER_INTEGRATIONS
environment variable, you can
explicitly pass in escherCredentialScope
and escherSecret
in config, which will be used
to generate the authentication headers. For this special use case version information have to
be included in the key, and only absolue url can be used.
escherRequest.get('http://localhost:45345/hello', {
escherKeyId: 'test_test-target_v1',
escherCredentialScope: 'eu/hap/ems_request',
escherSecret: 'secret'
});
The plan is to support most of axios's config options. url
, method
, headers
, data
,
params
and paramsSerializer
options are pre-processed, since they have direct impact
on the escher signature to be generated. All other options are passed down to axios unchanged.
One noticeable difference from the default options of axios
is the default value for
timeout
option. It is 25052 ms, while in axios
it is 0 (no timeout).
- escherRequest.get(url[, config])
- escherRequest.delete(url[, config])
- escherRequest.head(url[, config])
- escherRequest.options(url[, config])
- escherRequest.post(url[, data[, config]])
- escherRequest.put(url[, data[, config]])
- escherRequest.patch(url[, data[, config]])
Pre-signs an url with given expiration (in second, by default it is 86400 secs, aka 24 hours). Mostly useful for ui handshake requests or integrating an iframe into a front-end.
escherRequest.preSignUrl(
'http://www.example.com/etwas?a=4',
{ expires: 300 }
)
escherRequest.preSignUrl(
'/etwas?a=4',
{ expires: 300, escherKeyId: 'test_test-target' }
)
When passed in the credentialScope of the service and parameters of a received request, returns
whether it passes authentication or not (correct credentialScope
, keyId
, secret
, etc is used).
const { authenticated, message } = escherRequest.authenticate(
'eu/test-target/ems_request',
{
method: 'POST',
url: '/puty',
headers: {
'content-type': 'application/json',
host: 'localhost:9193',
'x-ems-date': '20190616T183748Z',
'x-ems-auth': 'EMS-HMAC-SHA256 Credential=test_test-target_v1 ...'
},
body: '{"duckling":4}'
}
)
autheticated
is boolean, shows whether it passed authentication or not, message
contains a reason if it did not.
Usually you want to wrap this method in a middlaware that handles the specifics of your favorite framework.
See examples for ideas how this could be done: koa, koa-with-badyparser, express, express-with-bodyparser
This package is currently maintained by @mkls. Feel free to reach out with problems, suggestions or anything through github issues.
Pull requests are always welcome, just follow our ordinal commit message convention.
Creating a new release:
- make your changes
- update version information in package.json
- document what was changed in CHANGELOG.md
- run
npm publish