{"id":15297230,"url":"https://github.com/uselessobject/authkeys","last_synced_at":"2026-05-09T00:37:53.405Z","repository":{"id":57187164,"uuid":"401242812","full_name":"uselessobject/authkeys","owner":"uselessobject","description":"🗝️ Create API \u0026 Server keys with Permissions and CustomData 🗝️","archived":false,"fork":false,"pushed_at":"2021-09-08T01:35:36.000Z","size":38,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2024-03-29T08:48:45.595Z","etag":null,"topics":["node-js","node-module","nodejs","nodejs-server","npm"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uselessobject.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-08-30T06:43:40.000Z","updated_at":"2021-09-08T01:35:39.000Z","dependencies_parsed_at":"2022-08-28T11:11:12.769Z","dependency_job_id":null,"html_url":"https://github.com/uselessobject/authkeys","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uselessobject%2Fauthkeys","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uselessobject%2Fauthkeys/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uselessobject%2Fauthkeys/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uselessobject%2Fauthkeys/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uselessobject","download_url":"https://codeload.github.com/uselessobject/authkeys/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245467614,"owners_count":20620216,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["node-js","node-module","nodejs","nodejs-server","npm"],"created_at":"2024-09-30T19:15:47.932Z","updated_at":"2026-05-09T00:37:53.373Z","avatar_url":"https://github.com/uselessobject.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🔑 AuthKeys\n\n![version](https://img.shields.io/badge/Version-v0.2.4-red)\n![express-support](https://img.shields.io/badge/Middleware-Available-yellow?logo=express)\n\nCreate API \u0026 Server keys with Permissions and CustomData\n\nThis tool was designed to improve permissions management, especially in HTTP and database tasks that works with *url-paths* to access to the stored data.\n\n***\n\nTable of Contents\n\n* 1. [Getting Started](#getting-started)\n  * 1.1. [Creating a Key](#creating-a-key)\n  * 1.2. [Custom Tokens](#custom-tokens)\n  * 1.3. [Updating Secret](#updating-secret)\n  * 1.4. [Adding CustomData](#adding-customdata)\n* 2. [Saving \u0026 Loading Keys](#saving-\u0026-loading-keys)\n  * 2.1. [Local Storage](#local-storage)\n  * 2.2. [Cloud Storage](#cloud-storage)\n* 3. [Permissions](#permissions)\n  * 3.1. [Managing Permissions](#managing-permissions)\n  * 3.2. [Check Permissions](#check-permissions)\n* 4. [Express Integration](#express-integration)\n  * 4.1. [Tokens in Client-Side](#tokens-in-client-side)\n    * 4.1.1. [Query Parameter](#query-parameter)\n    * 4.1.2. [Body Property](#body-property)\n    * 4.1.3. [Authorization Header](#authorization-header)\n* 5. [Full API Documentation](#api-documentation)\n\n##  1. \u003ca name='getting-started'\u003e\u003c/a\u003eGetting Started\n\nLet's create our first auth-key, but first, we need to install the package in our current *Node.js* project.\n\n```shell\nnpm install --save authkeys\n```\n\n###  1.1. \u003ca name='creating-a-key'\u003e\u003c/a\u003eCreating a Key\n\nIs really easy to make a new key to start adding permissions and custom-data (json).\nJust import the *AuthKey* class from the package or use the *createKey( )* method which uses the same parameters as the class.\n\n```javascript title=\"CommonJS\"\nconst { createKey, AuthKey } = require( \"authkeys\" ) ;\nlet key = createKey( ) ;\n// or\nlet key2 = new AuthKey( ) ;\n```\n\n```javascript title=\"ES6\"\nimport { createKey, AuthKey } from \"authkeys\" ;\nlet key = createKey( ) ;\n```\n\nBy default, the class constructor will create a token **(sha256 hash)** based in a random *secret* string and also it will add a random 32-length *public* password (can be useful or not, but I just added it to prevent).\n\n```javascript title=\"Result\"\nAuthKey {\n  \"token\"  : \"1696be1679f6696dd8e7bca9c7584e4a4916548d883d3e84dad3eec10c866a79\" ,\n  \"secret\" : \"RHJVpx4EQk1drllHmUmHfUShzejcqod0Lc1YLffqUDR6YHKaucPGtQj46TfG0OfU\" ,\n  \"public\" : \"WlagtNpeLnPlJmSuhVZYsNTpLPA3g9lP\" ,\n  \"permissions\" : { } ,\n  \"data\" : { }\n} ;\n```\n\n###  1.2. \u003ca name='custom-tokens'\u003e\u003c/a\u003eCustom Tokens\n\nThe *token* is the value used to identify your keys in a database.\nIn this way, you can use the token to make HTTP calls in a server, obtaining the `AuthKey` instance by searching its data in your database using the token as an ID.\n\nThe `AuthKey` class will generate a random token, but you can set your own *secret* string to generate it, even select the hash algorithm.\n\n```javascript title=\"Creating Custom-Tokens\"\nconst { createKey, AuthKey } = require( \"authkeys\" ) ;\n\n// Using a Custom Token-Value [v] ;\nlet key1 = createKey( \"my-custom-token-value\" ) ;\n\n// Generating a Token from a Secret-String [v] ;\n// You must set algorithm parameter to indicate that you want to generate a token from the first string.\nlet key2 = createKey( \"i-love-pizza\", \"sha256\" ) ;\n\nconsole.log( key1.token, key2.token ) ;\n```\n\n\u003cdetails\u003e\u003csummary\u003eSee Algorithms List (from crypto module)\u003c/summary\u003e\n\u003cp\u003e\n\n```shell title=\"Current list obtained from crypto module\"\nRSA-MD4\nRSA-MD5\nRSA-MDC2\nRSA-RIPEMD160\nRSA-SHA1\nRSA-SHA1-2\nRSA-SHA224\nRSA-SHA256\nRSA-SHA3-224\nRSA-SHA3-256\nRSA-SHA3-384\nRSA-SHA3-512\nRSA-SHA384\nRSA-SHA512\nRSA-SHA512/224\nRSA-SHA512/256\nRSA-SM3\nblake2b512\nblake2s256\nid-rsassa-pkcs1-v1_5-with-sha3-224\nid-rsassa-pkcs1-v1_5-with-sha3-256\nid-rsassa-pkcs1-v1_5-with-sha3-384\nid-rsassa-pkcs1-v1_5-with-sha3-512\nmd4\nmd4WithRSAEncryption\nmd5\nmd5-sha1\nmd5WithRSAEncryption\nmdc2\nmdc2WithRSA\nripemd\nripemd160\nripemd160WithRSA\nrmd160\nsha1\nsha1WithRSAEncryption\nsha224\nsha224WithRSAEncryption\nsha256\nsha256WithRSAEncryption\nsha3-224\nsha3-256\nsha3-384\nsha3-512\nsha384\nsha384WithRSAEncryption\nsha512\nsha512-224\nsha512-224WithRSAEncryption\nsha512-256\nsha512-256WithRSAEncryption\nsha512WithRSAEncryption\nshake128\nshake256\nsm3\nsm3WithRSAEncryption\nssl3-md5\nssl3-sha1\nwhirlpool\n```\n\u003c/p\u003e\n\u003c/details\u003e\n\n\n***\n\n###  1.3. \u003ca name='updating-secret'\u003e\u003c/a\u003eUpdating Secret\n\nMaybe you want to reset your users' API keys without deleting permissions, so you can change the `secret` property and then call `updateToken( )`.\n\nAbout the `public` password property, just change it like any other variable.\n\n```javascript\nconst { AuthKey } = require( \"authkeys\" ) ;\nlet key = new AuthKey( \"love-lemon-flavor\", \"sha256\" ) ;\nkey.secret = \"new-secret\" ;\nconst newToken = key.updateToken( ) ;\n\n// Update the token with a new algorithm [v] ;\nconst newMD5Token = key.updateToken( \"md5\" ) ;\n\n// Public-Password doesn't need to call updateToken( ) method.\n// Remember, tokens is just based on secret property. \nkey.public = \"new-public-password\" ; \n```\n\n###  1.4. \u003ca name='adding-customdata'\u003e\u003c/a\u003eAdding CustomData\n\n*CustomData* is just a little feature to store **simple data** (strings, numbers, booleans or even objects) in our keys.\n\n```javascript\n// SET [v] ;\nkey.data( \"key\", \"value\" ) ;\nkey.data( \"pizza\", true ) ;\n\n// GET [v] ;\nvar wantPizza = key.data( \"pizza\" ) ;\n```\n\n***\n\n##  2. \u003ca name='saving-\u0026-loading-keys'\u003e\u003c/a\u003eSaving \u0026 Loading Keys\n\n###  2.1. \u003ca name='local-storage'\u003e\u003c/a\u003eLocal Storage\n\nSave your current key data (hexadecimal) in your drive and then load it with all its permissions and custom-data.\n\n```javascript title=\"Saving File\"\nconst { createKey } = require( \"authkeys\" ) ;\nlet key = createKey( ) ;\nkey.save( \"./api.key\" ) ;\n```\n\n```javascript title=\"Loading File\"\nconst { AuthKey, loadKey } = require( \"authkeys\" ) ;\nlet key = AuthKey.load( \"./api.key\" ) ;\n// or\nlet key = loadKey( \"./api.key\" ) ;\n```\n\n###  2.2. \u003ca name='cloud-storage'\u003e\u003c/a\u003eCloud Storage\n\nSometimes we will need to save the key in a cloud-storage or database, so we can get a **JSON** and then parse it into a new *AuthKey*.\n\n```javascript title=\"Get JSON\"\nlet obj = key.toJSON( ) ;\n```\n\n```javascript title=\"Parse JSON\"\nconst { AuthKey, parseKey } = require( \"authkeys\" ) ;\nlet key = AuthKey.parse( obj ) ;\n// or\nlet key = parseKey( obj ) ;\n```\n\n***\n\n##  3. \u003ca name='permissions'\u003e\u003c/a\u003ePermissions\n\nPermissions are a bit more difficult, that's why we set it aside in a separate section.\nYou just need to understand that permissions work based on *url-paths* or *IDs*.\n\n**Note:** The *AuthKey* permissions structure are useful for HTTP servers, but they aren't exclusive for that.\n\n###  3.1. \u003ca name='managing-permissions'\u003e\u003c/a\u003eManaging Permissions\n\nYou can set multiple permissions using url-patterns with `permission( pattern\u003cstring\u003e, permissions-action\u003cstring\u003e )` method.\nJust add `+` or `-` symbol at the beginning of the string and then add the first letter of each type of permission.\n\n```shell title=\"Available Permission-Types\"\nr = read\nw = write\nd = delete \nx = execute\n```\n\n```javascript title=\"Adding Permissions\"\nkey.permission( \"id1\", \"+wr\" ) ;\nkey.permission( \"/users/*\", \"+r\" ) ;\n```\n\n```javascript title=\"Removing Permissions\"\nkey.permission( \"id1\", \"-w\" ) ;\nkey.permission( \"/users/*\", \"-d\" ) ;\n```\n\n**Note:** *What happens if I type a letter twice or enter an initial that is not available?* Actually nothing, it will be ignored.\n\n:::tip\n\nIf you will use AuthKeys with Express.js, don't forget to add a slash (`/`) at the beginning of the permissions url-pattern. On this way, you can check permissions using `req.path` property.\n\n:::\n\n###  3.2. \u003ca name='check-permissions'\u003e\u003c/a\u003eCheck Permissions\n\nIt's really easy to check all available permissions (even those that have not been added), just remove the **symbol (+/-)** from the string and use only one permission type.\nAlso you can use `checkPermissions(pattern\u003cstring\u003e)` method instead to return all permissions in an object.\n\n```javascript title=\"Checking Single-Permission\"\nconst canRead    = key.permission( \"id1\", \"r\" ) ;\nconst canWrite   = key.permission( \"/users/blitzcrank\", \"w\" ) ; \nconst canDelete  = key.permission( \"/a/pattern/that/does/not/coincide\", \"r\" ) ; // \u003c= It will return false instead an error.\nconst canExecute = key.permission( \"id1\", \"rw\" ) ; // \u003c= Not allowed. \n```\n\n```javascript title=\"Using checkPermissions() Method\"\n// This method will return all permissions (added or not) in an object.\nif( key.checkPermissions( \"users/blitzcrank\" ).read === true ) {\n  // do something...\n}\n```\n\n***\n\n##  4. \u003ca name='express-integration'\u003e\u003c/a\u003eExpress Integration\n\nThe `AuthKey` middleware will allow you to have a direct access to the permissions of all your keys and their data in **every HTTP call in your Express.js** server, \nusing an optional cache system to save time and resources. \n\n**See:** [How middlewares works in Express.js](https://expressjs.com/en/guide/using-middleware.html)\n\n```javascript title=\"ES6 Import\"\nimport { middleware as authkeys, loadKey, createKey } from \"authkeys\" ;\n```\n\n```javascript title=\"Quick Example (CommonJS)\"\nconst { loadKey, createKey } = require( \"authkeys\" ) ;\nconst authkeys = require( \"authkeys\" ).middleware ;\nconst express = require( 'express' ) ;\nconst app = express( ) ;\nconst port = 3000 ;\nconst fs  = require( \"fs\" ) ;\n\n// Creating a Local-Key for Test [v] ;\nlet authKey = createKey( ) ;\nauthKey.permission( \"/API/*\", \"+rw\" ) ;\nconst keysPath = \"./keys/\" ;\nif( !fs.existsSync( keysPath ) ) { fs.mkdirSync( keysPath ) ; }\nauthKey.save( \"./keys/test.key\" ) ;\n\n// CONFIGURE MIDDLEWARE [v] ;\nconst ENABLE_CACHE_KEYS = true ;\nconst AUTH_KEYS_GET = function( token ) {\n  /* [!] How auth-keys will be loaded or requested.\n  // In this example we will get keys from a folder in the server-root.\n  // You can load keys from a database like Firestore from Firebase.\n  // Just remember to return the result ;\n  // ---------------------------------- ; */\n  let key = null ;\n  keyFiles = fs.readdirSync( keysPath ) ;\n  keyFiles.forEach( file =\u003e {\n    if( key ) { return false ; }\n    // load and check [v] ;\n    var k = loadKey( keysPath + file ) ;\n    if( k.token === token ) { return key = k ; }\n  } ) ;\n  // If key == null, a 400 response will be returned.\n  // The result can be a parsable object or an AuthKey instance.\n  return key ;\n} ;\n\n/* Check Keys only in any url under /API/ path. */\napp.use( \"/API/*\", authkeys( AUTH_KEYS_GET, ENABLE_CACHE_KEYS ) ) ;\n\napp.get( '/API/users', (req, res) =\u003e {\n  // Checking Permissions\n  const auth = req.authKey ; /* \u003c= AuthKey instance. */\n  const list = req.permissions ; /* \u003c= All permissions for the current URL. */\n  return res.send( list ) ;\n} ) ;\n\napp.listen( port, ( ) =\u003e {\n  console.log( `Example app listening at http://localhost:${port}` ) ;\n  console.log( \"TOKEN =\u003e \" + authKey.token ) ;\n} ) ;\n\n/* Go to http://localhost:3000/API/users?token=${ token-value } */\n```\n\n###  4.1. \u003ca name='tokens-in-client-side'\u003e\u003c/a\u003eTokens in Client-Side\n\nYou can set the token in your HTTP requests in 3 different ways: *Query Parameter*, *Body Property* and *Authorization Header*.\nThe **middleware** will automatically search all this parameters (in the previous order) in every request.\n\n####  4.1.1. \u003ca name='query-parameter'\u003e\u003c/a\u003eQuery Parameter\nJust add the `token` query parameter to the URL.\n\n```shell\ncurl http://localhost:3000/API/users?token=TOKEN_VALUE\n```\n\n####  4.1.2. \u003ca name='body-property'\u003e\u003c/a\u003eBody Property\nAdd the `token` property to your body-data.\n\n```shell\ncurl --header \"Content-Type: application/json\" \\\n  --request POST \\\n  --data '{\"token\":\"TOKEN_VALUE\"}' \\\n  http://localhost:3000/API/users\n```\n\n####  4.1.3. \u003ca name='authorization-header'\u003e\u003c/a\u003eAuthorization Header\n\n```shell\ncurl http://localhost:3000/API/users\n  -H \"Authorization: {TOKEN_VALUE}\"\n```\n\n***\n\n##  5. \u003ca name='api-documentation'\u003e\u003c/a\u003eFull API Documentation\n\nTo see full API documentation please open the API.md file in the official [github repository](https://github.com/uselessobject/authkeys/blob/main/API.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuselessobject%2Fauthkeys","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuselessobject%2Fauthkeys","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuselessobject%2Fauthkeys/lists"}