auth-server-helper
version: 4.1.x
customizable and simple authentication
Installation
npm:
npm i --save auth-server-helper
yarn:
yarn add auth-server-helper
Usage
1. put a gateway in front of the routes you want to secure
const {create_gateway} = require('@sapphirecode/auth-server-helper');
const gateway = create_gateway({
redirect_url: '/auth',
cookie: { name: 'auth_cookie' },
refresh_cookie: { name: 'refresh_cookie' },
refresh_settings: {
}
});
app.use(gateway);
http.createServer((main_req, main_res) =>
gateway(main_req, main_res, (req, res) => {
});
);
the gateway will forward any authorized requests to the next handler and
redirect all others to the specified url
1.1. Creating a gateway for manual processing of requests
const {GatewayClass} = require('@sapphirecode/auth-server-helper');
const gateway = new GatewayClass({ });
if (gateway.authenticate(http_request)) {
console.log('access granted');
} else {
gateway.redirect(response);
gateway.deny(response);
}
2. creating the auth endpoint
const {create_auth_handler} = require('@sapphirecode/auth-server-helper');
const handler = create_auth_handler(
async (req) => {
if (req.user === 'foo' && req.password === 'bar')
const {access_token_id, refresh_token_id} = await req.allow_access({
access_token_expires_in: 600,
include_refresh_token: true,
refresh_token_expires_in: 3600,
data: {user: 'foo'},
});
if (req.user === 'part' && req.password === 'baz')
const part_id = await req.allow_part(
60,
'some_module',
{foo: 'bar'}
);
req.deny();
},
{
refresh: {
},
modules: {
some_module(req) {
const auth_data = req.request.connection.auth;
auth_data.token_id;
auth_data.token_data;
},
},
cookie: { name: 'auth_cookie' },
refresh_cookie: { name: 'refresh_cookie' },
parse_body: true
}
);
app.use(handler);
handler(req, res);
after the auth handler, the request will be completed, no additional content
should be served here. (Read 2.1 for info on disabling this)
2.1. Processing Auth Requests without closing the response object
to prevent the auth handler from closing the response object you can provide
additional options on each of the allow/deny functions.
allow_access({leave_open: true, ...});
allow_part(
60,
'some_module',
{foo: 'bar'},
true
);
invalid('error description', true);
deny(true);
if this flag is set, no data will be written to the response body and no data
will be sent. Status code and Headers will still be set.
Defining Custom Cookie Settings
By default all cookies will be sent with 'Secure; HttpOnly; SameSite=Strict'
Attributes
In the appropriate settings object, you can set the following options:
{
name: 'foo',
secure: true,
http_only: true,
same_site: 'Strict',
expires: 'Mon, 10 Jan 2022 09:28:00 GMT',
max_age: 600,
domain: 'example.com',
path: '/cookies_here'
}
For Documentation on the different Cookie Attributes see
https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#creating_cookies
Invalidating tokens after they are delivered to the client
const {blacklist} = require('@sapphirecode/auth-server-helper');
await blacklist.add_signature(token_id);
Logout function
const {GatewayClass} = require('@sapphirecode/auth-server-helper');
const gateway = new GatewayClass({ });
app.get('logout', (req, res) => {
gateway.logout(req);
res.status(200);
res.end();
});
Exporting and importing public keys to validate tokens across server instances
const {keystore} = require('@sapphirecode/auth-server-helper');
const export = keystore.export_verification_data();
keystore.import_verification_data(export);
These keys can also be live synchronized with redis to allow sessions to be
shared between servers
const {keystore} = require('@sapphirecode/auth-server-helper');
keystore.sync_redis('redis://localhost');
Exporting and importing blacklist entries across server instances
const {blacklist} = require('@sapphirecode/auth-server-helper');
const export = blacklist.export_blacklist();
blacklist.import_blacklist(export);
Clearing Keystore and Blacklist
Resetting the Keystore instance generates a new instance id and deletes all
imported or generated keys.
const {keystore, blacklist} = require('@sapphirecode/auth-server-helper');
keystore.reset_instance();
await blacklist.clear();
await blacklist.clear(Date.now() - 10000);
Setting and checking permissions
When allowing access to a client a list of permissions can be added. Permissions
are case sensitive.
allow_access({permissions: ['foo','bar'], ...})
The gateway can be told to check those permissions before forwarding a request.
const gateway = new GatewayClass({
require_permissions: ['foo'],
});
additional checks can be run later
(req, res) => {
const has_both = gateway.check_permissions(req, ['foo', 'bar']);
const has_bar = gateway.has_permission(req, 'bar');
};
Reading connection info
Data like the used token id, custom data and permissions can be read from
req.connection.auth
or using the function gateway.get_info(req)
const info = gateway.get_info(req);
console.log(info);
License
MIT © Timo Hocker timo@scode.ovh