npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@taylorgrinn/auth-mysql-redis

v1.0.0-alpha.1

Published

Auth server with built-in MySQL user model and redis store.

Readme

Tay Auth MySQL Redis

This is an express authentication server meant to be used with Nginx's auth_request command.

Installation

npm i --save @taylorgrinn/auth-mysql-redis
yarn add @taylorgrinn/auth-mysql-redis

Usage

Use the default async function to create an authentication server.

const createServer = require('@taylorgrinn/auth-mysql-redis').default;

const PORT = 8080;

createServer({
  secret: 'sshhhh',
}).then((auth) =>
  auth.listen(PORT, () => console.log(`Auth server listening on port ${PORT}.`))
);

The secret option or AUTH_SECRET environment variable must be set.

By default, it will use an in-memory store and Users model which will be cleared every time the server restarts.

To connect to a Redis instance, either supply the option redis.url or the environment variable REDIS_URL.

To connect to a MySQL server, specify both the host and database using either mysql.host or MYSQL_HOST and either mysql.database or MYSQL_DB.

createServer({
  secret: 'sssshhh',
  redis: {
    url: 'redis://localhost:6379',
  },
  mysql: {
    host: 'localhost',
    database: 'tay_dev',
  },
});

The server will send a 401 Unauthorized status code for anyone not logged in and a 200 Success status code otherwise. To customize this behavior, pass in a verify RequestHandler. Within this handler, req.user will contain the user info.

createServer({
  secret: 'ssshhhh',
  verify(req, res) {
    console.log('Verifying request', req.originalUrl);
    if (req.user.email === '[email protected]') res.sendStatus(200);
    else res.sendStatus(403);
  },
});

Nginx setup

Create an internal location for verifying requests using the auth server.

location = /verify {
    internal;
    proxy_pass http://localhost:8080/verify$request_uri;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
}

Where localhost:8080 is the location of the authentication server accessible to Nginx.

In order to login or register an account, you'll need to expose the /auth REST API from the authentication server.

location /auth {
    proxy_pass http://localhost:8080/auth;
}

You can use auth_request /verify; to protect any location.

location / {
    auth_request /verify;
    index index.html;
    try_files $uri $uri.html $uri/ =404;
}

Finally you'll need to build a portal which will be served when a 401 status is received from the authentication server.

location = /portal.html {
    internal;
}

error_page 401 /portal.html;

portal.html must exist at the root of the website and should allow users to login or register an account.

You can see an example of all this together at demo/nginx.conf

Setup the external providers (Google, Github, Facebook)

In order to set up external providers, the authBaseUrl option or AUTH_BASE_URL environment variable must be set to the publicly available address of the auth REST API. In the Nginx config above, it is available at /auth, so the authBaseUrl will be https://taydev.org/auth.

Create API keys for each or any of the services:

When creating the keys for each provider, you'll also have to specify the callback urls in this format:

  • Google: `${authBaseUrl}/google/callback`
  • Github: `${authBaseUrl}/github/callback`
  • Facebook: `${authBaseUrl}/facebook/callback`

Add the keys, as well as the external location of your authentication server, to the createServer options:

createServer({
  ...,
  authBaseUrl: 'https://taydev.org/auth', // Used for callbacks after authentication
  google: {
    clientId: 'blahblahblah',
    clientSecret: 'blahblahblah',
    scope: [], // Optional: scopes allow you to get more user information
  },
  github: {
    clientId: 'blahblahblah',
    clientSecret: 'blahblahblah',
    scope: [], // Optional: scopes allow you to get more user information
  },
  facebook: {
    clientId: 'blahblahblah',
    clientSecret: 'blahblahblah',
    scope: [], // Optional: scopes allow you to get more user information
    profileFields: [] // Optional: profile fields need to be specified for user object
  }
});

For the scope options, the email scope is already included in all authentication requests by default.

Auth Server Options

Order of precedence: env var > option > default
Array environment variables are comma separated: MY_VAR=thing1,thing2

| option | required | env var | type | description | | ---------------------- | --------------------- | ----------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | secret | required | AUTH_SECRET | string | string[] | Provide a secret key or list of keys to use for creating sessions. | | verify | optional | | express.RequestHandler | This handler will be called for each authentication request from the web server. It should call res.sendStatus(403) for forbidden requests or res.sendStatus(200) for an allowed request. If a request is not handled (ie next() was called), a 200 Success response will be sent. | | sendCode | optional | | (emailAddress: string, code: string) => Promise<any> | Send a reset code to a specified email address. The user can then copy this code into the reset password form to recover access to their account | | delay | optional | AUTH_DELAY | number | Milliseconds to delay each request to the auth server. | | cors | optional | CORS | boolean (string[] if using env var) | Set the cookie properties: sameSite: true, secure: true. This will allow cookies to be loaded from any domain and requires the authentication server to be served over https. See the demo folder for an example of serving https://localhost using custom certificates. See below for more info | | httpOnly | optional | HTTP_ONLY | boolean | Whether the cookie willl have the httpOnly flag. True, by default. | | authBaseUrl | required for external | AUTH_BASE_URL | string | The external address of your authentication server. This option is required for an identity provider like google or github to redirect users back after signing in but not for local sign in, register or reset password | | google.clientID | required for google | GOOGLE_CLIENT_ID | string | Client ID given by Google. | | google.clientSecret | required for google | GOOGLE_CLIENT_SECRET | string | Client secret given by Google. | | google.scope | optional | GOOGLE_SCOPE | string[] | Scope of information or abilities to be requested by you to the user for their Google account. The 'email' scope is added to all requests in addition to any you specify here | | github.clientID | required for github | GITHUB_CLIENT_ID | string | Client ID given by Github. | | github.clientSecret | required for github | GITHUB_CLIENT_SECRET | string | Client secret given by Github. | | github.scope | optional | GITHUB_SCOPE | string[] | Scope of information or abilities to be requested by you to the user for their Github account. The 'user:email' scope is added to all requests in addition to any you specify here | | facebook.clientID | required for facebook | FACEBOOK_CLIENT_ID | string | Client ID given by Facebook. | | facebook.clientSecret | required for facebook | FACEBOOK_CLIENT_SECRET | string | Client secret given by Facebook. | | facebook.scope | optional | FACEBOOK_SCOPE | string[] | Scope of information or abilities to be requested by you to the user for their Facebook account. The 'email' scope is added to all requests in addition to any you specify here | | facebook.profileFields | optional | FACEBOOK_PROFILE_FIELDS | string[] | Profile fields to include when authenticating. The 'email' field is added to all requests in addition to any you specify here |

Redis Options

| option | required | env var | type | description | | -------------- | -------- | -------------- | ------ | -------------------------------------------------------------------------- | | redis.url | required | REDIS_URL | string | The Redis connection url to use. | | redis.user | optional | REDIS_USER | string | The user to log in to the Redis instance as. | | redis.password | optional | REDIS_PASSWORD | string | Password to use for connecting to the Redis instance. | | redis.name | optional | REDIS_NAME | string | A name to assign the Redis connection. | | redis.database | optional | REDIS_DB | number | The database to connect to [0-15] | | redis.ttl | optional | REDIS_TTL | number | The number of seconds a session should last (1 day by default). | | redis.prefix | optional | REDIS_PREFIX | string | A string to prepend each session in the Redis database (sess: by default). |

Other options are documented in RedisClientOptions from the @redis/client package and RedisStoreOptions from the connect-redis package.

MySQL Options

When connecting to MySQL, this library creates a users table in the configured database. The host and database are required options.

| option | required | env var | type | description | | -------------- | -------- | ---------- | ------ | -------------------------------------------- | | mysql.host | required | MYSQL_HOST | string | The hostname to connect to. | | mysql.port | optional | MYSQL_PORT | number | The port the MySQL server is running on. | | mysql.user | optional | MYSQL_USER | string | The username to use for the MySQL server. | | mysql.password | optional | MYSQL_PASS | string | The password to use for the MySQL server. | | mysql.database | required | MYSQL_DB | string | The database to create the 'users' table in. |

Other options are specified in PoolOptions from the mysql2 package.

Setup cors for cross-domain authentication

If your authentication server is on a different domain than your client, or you have multiple clients logging in to the same authentication server, you can use the cors option or the CORS environment variable.

createServer({
  ...,
  cors: ['https://taydev.org', 'https://localhost:8081'],
});

The cors option takes in any number of whitelisted domains and adds the relevant headers to all requests from each of them.

The cors option or CORS environment variable changes the way cookies are set. Specifically, it makes them available on any domain and makes them secure, only available when the authentication server is served over https. Check out the demo folder to see an example of serving https://localhost with a self-signed certificate.

If the CORS environment variable is set, the whitelist will be set to the comma-separated list value.

# .env file (or however you set env vars)
CORS=https://taydev.org,https://localhost:8081

/auth REST API

The auth server accepts application/json, multipart/form-data, and application/x-www-form-urlencoded bodies. The JSON format is shown below.

| route | method | body | return | description | | --------- | ------ | ----------------------------------- | -------------------- | --------------------------------------------------------- | | /register | POST | { email: string, password: string } | User | Register a new account. | | /login | POST | { email: string, password: string } | User | Login to an existing account. | | /verify | GET | | User | Verify that you are logged in an access the current user. | | /logout | PUT | | { success: boolean } | Logout of the current account. | | /user | DELETE | | { success: boolean } | Delete the current user account |

Add a login link for each external provider configured (google, facebook, or github). The query paramter redirect is required and should be URI encoded.

<a href="/auth/google?redirect=https%3A%2F%2Ftaydev.org">Google Login</a>

In order to come back to the current page after authentication, use location.href for the redirect.

<script>
  function authFacebook() {
    const redirect = encodeURIComponent(location.href);
    location.href = '/auth/facebook?redirect=' + redirect;
  }
</script>
<button onclick="authFacebook()">Facebook Login</button>