{"id":15984241,"url":"https://github.com/lionc/express-basic-auth","last_synced_at":"2025-04-08T09:07:47.533Z","repository":{"id":11273283,"uuid":"69027751","full_name":"LionC/express-basic-auth","owner":"LionC","description":"Plug \u0026 play basic auth middleware for express","archived":false,"fork":false,"pushed_at":"2023-01-23T21:54:16.000Z","size":197,"stargazers_count":324,"open_issues_count":19,"forks_count":56,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-05-20T01:43:16.312Z","etag":null,"topics":["basic-authentication","express","express-middleware","middleware","node"],"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/LionC.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":"2016-09-23T13:34:51.000Z","updated_at":"2024-04-19T23:20:16.000Z","dependencies_parsed_at":"2023-02-13T03:45:55.520Z","dependency_job_id":null,"html_url":"https://github.com/LionC/express-basic-auth","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LionC%2Fexpress-basic-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LionC%2Fexpress-basic-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LionC%2Fexpress-basic-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LionC%2Fexpress-basic-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LionC","download_url":"https://codeload.github.com/LionC/express-basic-auth/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247809962,"owners_count":20999816,"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":["basic-authentication","express","express-middleware","middleware","node"],"created_at":"2024-10-08T02:05:17.985Z","updated_at":"2025-04-08T09:07:47.512Z","avatar_url":"https://github.com/LionC.png","language":"JavaScript","readme":"# express-basic-auth\n\n[![npm version](https://badge.fury.io/js/express-basic-auth.svg)](https://badge.fury.io/js/express-basic-auth)\n[![npm](https://img.shields.io/npm/dm/express-basic-auth.svg)]()\n[![CircleCI](https://circleci.com/gh/LionC/express-basic-auth/tree/master.svg?style=shield\u0026circle-token=74f7b1557100b45259e67d2492c263e4f99365d4)](https://circleci.com/gh/LionC/express-basic-auth/tree/master)\n[![David](https://img.shields.io/david/strongloop/express.svg)]()\n![TypeScript compatible](https://img.shields.io/badge/typescript-compatible-brightgreen.svg)\n[![MIT Licence](https://badges.frapsoft.com/os/mit/mit.svg?v=103)](https://opensource.org/licenses/mit-license.php)\n\nSimple plug \u0026 play HTTP basic auth middleware for Express.\n\n## How to install\n\nJust run\n\n```shell\nnpm install express-basic-auth\n```\n\n## How to use\n\nThe module will export a function, that you can call with an options object to\nget the middleware:\n\n```js\nconst app = require('express')()\nconst basicAuth = require('express-basic-auth')\n\napp.use(basicAuth({\n    users: { 'admin': 'supersecret' }\n}))\n```\n\nThe middleware will now check incoming requests to match the credentials\n`admin:supersecret`.\n\nThe middleware will check incoming requests for a basic auth (`Authorization`)\nheader, parse it and check if the credentials are legit. If there are any\ncredentials, an `auth` property will be added to the request, containing\nan object with `user` and `password` properties, filled with the credentials,\nno matter if they are legit or not.\n\n**If a request is found to not be authorized**, it will respond with HTTP 401\nand a configurable body (default empty).\n\n### Static Users\n\nIf you simply want to check basic auth against one or multiple static credentials,\nyou can pass those credentials in the `users` option:\n\n```js\napp.use(basicAuth({\n    users: {\n        'admin': 'supersecret',\n        'adam': 'password1234',\n        'eve': 'asdfghjkl',\n    }\n}))\n```\n\nThe middleware will check incoming requests to have a basic auth header matching\none of the three passed credentials.\n\n### Custom authorization\n\nAlternatively, you can pass your own `authorizer` function, to check the credentials\nhowever you want. It will be called with a username and password and is expected to\nreturn `true` or `false` to indicate that the credentials were approved or not.\n\nWhen using your own `authorizer`, make sure **not to use standard string comparison (`==` / `===`)**\nwhen comparing user input with secret credentials, as that would make you vulnerable against\n[timing attacks](https://en.wikipedia.org/wiki/Timing_attack). Use the provided `safeCompare`\nfunction instead - always provide the user input as its first argument. Also make sure to use bitwise\nlogic operators (`|` and `\u0026`) instead of the standard ones (`||` and `\u0026\u0026`) for the same reason, as\nthe standard ones use shortcuts.\n\n```js\napp.use(basicAuth( { authorizer: myAuthorizer } ))\n\nfunction myAuthorizer(username, password) {\n    const userMatches = basicAuth.safeCompare(username, 'customuser')\n    const passwordMatches = basicAuth.safeCompare(password, 'custompassword')\n\n    return userMatches \u0026 passwordMatches\n}\n```\n\nThis will authorize all requests with the credentials 'customuser:custompassword'.\nIn an actual application you would likely look up some data instead ;-) You can do whatever you\nwant in custom authorizers, just return `true` or `false` in the end and stay aware of timing\nattacks.\n\n### Custom Async Authorization\n\nNote that the `authorizer` function above is expected to be synchronous. This is\nthe default behavior, you can pass `authorizeAsync: true` in the options object to indicate\nthat your authorizer is asynchronous. In this case it will be passed a callback\nas the third parameter, which is expected to be called by standard node convention\nwith an error and a boolean to indicate if the credentials have been approved or not.\nLet's look at the same authorizer again, but this time asynchronous:\n\n```js\napp.use(basicAuth({\n    authorizer: myAsyncAuthorizer,\n    authorizeAsync: true,\n}))\n\nfunction myAsyncAuthorizer(username, password, cb) {\n    if (username.startsWith('A') \u0026 password.startsWith('secret'))\n        return cb(null, true)\n    else\n        return cb(null, false)\n}\n```\n\n### Unauthorized Response Body\n\nPer default, the response body for unauthorized responses will be empty. It can\nbe configured using the `unauthorizedResponse` option. You can either pass a\nstatic response or a function that gets passed the express request object and is\nexpected to return the response body. If the response body is a string, it will\nbe used as-is, otherwise it will be sent as JSON:\n\n```js\napp.use(basicAuth({\n    users: { 'Foo': 'bar' },\n    unauthorizedResponse: getUnauthorizedResponse\n}))\n\nfunction getUnauthorizedResponse(req) {\n    return req.auth\n        ? ('Credentials ' + req.auth.user + ':' + req.auth.password + ' rejected')\n        : 'No credentials provided'\n}\n```\n\n### Challenge\n\nPer default the middleware will not add a `WWW-Authenticate` challenge header to\nresponses of unauthorized requests. You can enable that by adding `challenge: true`\nto the options object. This will cause most browsers to show a popup to enter\ncredentials on unauthorized responses. You can set the realm (the realm\nidentifies the system to authenticate against and can be used by clients to save\ncredentials) of the challenge by passing a static string or a function that gets\npassed the request object and is expected to return the challenge:\n\n```js\napp.use(basicAuth({\n    users: { 'someuser': 'somepassword' },\n    challenge: true,\n    realm: 'Imb4T3st4pp',\n}))\n```\n\n## Try it\n\nThe repository contains an `example.js` that you can run to play around and try\nthe middleware. To use it just put it somewhere (or leave it where it is), run\n\n```shell\nnpm install express express-basic-auth\nnode example.js\n```\n\nThis will start a small express server listening at port 8080. Just look at the file,\ntry out the requests and play around with the options.\n\n## TypeScript usage\n\nA declaration file is bundled with the library. You don't have to install a `@types/` package.\n\n```typescript\nimport * as basicAuth from 'express-basic-auth'\n```\n\n:bulb: **Using `req.auth`**\n\nexpress-basic-auth sets `req.auth` to an object containing the authorized credentials like `{ user: 'admin', password: 'supersecret' }`.\n\nIn order to use that `req.auth` property in TypeScript without an unknown property error, use covariance to downcast the request type:\n\n```typescript\napp.use(basicAuth(options), (req: basicAuth.IBasicAuthedRequest, res, next) =\u003e {\n    res.end(`Welcome ${req.auth.user} (your password is ${req.auth.password})`)\n    next()\n})\n```\n\n:bulb: **A note about type inference on synchronous authorizers**\n\nDue to some TypeScript's type-system limitation, the arguments' type of the synchronous authorizers are not inferred.\nFor example, on an asynchronous authorizer, the three arguments are correctly inferred:\n\n```typescript\nbasicAuth({\n    authorizeAsync: true,\n    authorizer: (user, password, authorize) =\u003e authorize(null, password == 'secret'),\n})\n```\n\nHowever, on a synchronous authorizer, you'll have to type the arguments yourself:\n\n```typescript\nbasicAuth({\n    authorizer: (user: string, password: string) =\u003e (password == 'secret')\n})\n```\n\n## Tests\n\nThe cases in the `example.js` are also used for automated testing. So if you want  \nto contribute or just make sure that the package still works, simply run:\n\n```shell\nnpm test\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flionc%2Fexpress-basic-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flionc%2Fexpress-basic-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flionc%2Fexpress-basic-auth/lists"}