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 🙏

© 2024 – Pkg Stats / Ryan Hefner

cubic-auth

v3.2.3

Published

Auth Server for Cubic.

Downloads

9

Readme

cubic-auth

npm build dependencies

Usage

const Cubic = require('cubic')
const Auth = require('cubic-auth')
const cubic = new Cubic()

cubic.use(new Auth(options))

| Option | Default | Description | |:------------- |:------------- |:------------- | | exp | '1h' | Access token expiration date since being issued. | | alg | 'RS256' | JWT signature algorithm | | certPrivate | none | String of private RSA key used for JWT signature. (This is set automatically in dev mode) | | certPublic | none | String of public RSA key used to verify JWT signature. (Set automatically in dev mode) | | certPass | none | Optional secret to decrypt the provided RSA keys | | maxLogsPerUser | 50 | Number of access logs for each user | | api | <object> | Configure internal cubic-api node. See override options below. | | core | <object> | Configure internal cubic-core node.

How does it work?

Imagine this: You're a happy little web-app that wants to get data from a Web API. However, that API endpoint is only open to authorized users. The API will only let us in if we show it a document explaining who we are, which is signed by a trusted authority.

In our case, the auth server is that trusted authority. To get the document, we just need to provide the username and passphrase used when registering our account and we'll get the signed document (the access token) in return.

Since the access token is signed by the trusted authority, the API believes what the access token tells about the user and sees if they have the required permission to access the desired API endpoint.

model You usually don't have to bother with these concepts when building your application, but it might help your understanding of the framework in general. If you wanna know even more details, here's a quick rundown of the main endpoints that are exposed on the auth API:

/authenticate

POST /authenticate

Body:

{
 user_key: <key>,
 user_secret: <password>,

 redirect: <url>,
 cookie_set: <boolean>,
 cookie_longliving: <boolean>
}

Response:

{
 access_token: <access_token>,
 refresh_token: <refresh_token>
}

Used to verify a user that is stored in the auth database. If the user/password matches, this returns an access_token and refresh_token.

The access_token is a short-lived (1h by default) JSON Webtoken (JWT) containing all important user data (name, permissions, etc). It is highly recommended to look at how they work at jwt.io.

cubic-auth uses the RSA256 signature algorithm to generate a signature from the plaintext payload with an RSA private key. This signature ensures that the data provided in the payload hasn't been modified or forged by an attacker. By signing the token with RSA keys, we can later use the public key on cubic-api nodes to verify the signature - without exposing our private key in case of a security breach.

The last three options are for http client auth and optional. redirect takes an url to redirect to, instead of the standard json response. If cookie_set has a value, a base64 encoded cookie containing an object with the access_token and refresh_token is set, which expires at end of session or, if cookie_longliving has a value, at a later date (30d by default).

/refresh

POST /refresh

Body:

{
 refresh_token: <refresh_token>
}

Response:

{
 access_token: <access_token>
}

Used to generate new access tokens from the provided refresh token.

The refresh_token is the token used to ask for new access tokens once they expired. It's long-lived (i.e. doesn't expire unless reset for security reasons), and looks like user_id + 256bit string to ensure an unguessable token which is unique to the user.

The reason access tokens are short-lived is to reduce the time an attacker gets in the case of access tokens being leaked. There's no way to revoke the permissions granted by stateless JWTs, but it's easy to revoke a single refresh token.

/register

POST /register

Body:

{
 user_id: <username>,
 user_secret: <password>
}

Response:

{
 user_key: <key>
}

Used to save new users to the database. Passwords are hashed with bcrypt at 8 salt rounds. Please make sure you're using HTTPS, otherwise someone could intercept the plaintext password.

/userkey

POST /userkey

Body:

{
 user_id: <username>,
 user_secret: <password>
}

Response:

{
 user_key: <key>
}

Used for getting your corresponding user_key. Important when authenticating through the API, after it has been discarded from the /register endpoint. The user_key is not sensitive, but we still keep it hidden for privacy.

Getting the access tokens to the target API

Now that we have the access token, the question still remains how we get it on the API node and how we can read the data from cubic-core endpoints.

On the client

For http requests, just put the access token in the auth header. With node's 'requests' library, the options object would look something like this:

{
  header: {
    authorization: 'bearer <access_token>'
  }
}

For WebSockets we have to send the token with the intial handshake. Just put this as the options object when connecting:

{
  query: 'bearer=<access_token>'
}

Note that these things are taken care of automatically with the cubic-client package. The examples merely serve for clarification, but you shouldn't actually have to use them manually.

On the API node

On the API node we have a default middleware function that verifies the WebSocket handshake as well as the authorization header on every http request, by verifying the token signature with the provided RSA public key.

Should the verification fail, a 401 error message will be returned. Should no token be provided, we'll just pass the default user with no special permissions.

If the verification succeeds or no token is provided, the payload (or default user) is attached to req.user. This is the same req object that we later have access to on a cubic-core endpoint. With the verification performed beforehand, we can be certain that whatever data we get in req.user will be valid.

The scope specified in req.user.scp will also be automatically compared to this.schema.scope inside an endpoint. Should it not match, a 401 error will be returned.

Override config

Since the cubic-auth server is completely based on a regular cubic setup, we can configure the cubic-api and cubic-core options individually. Below are the overrides used by default.

cubic-api

| Api Option | Override | Description | |:------------- |:------------- |:------------- | | port | 3030 | Port to listen on for requests. | | cacheDb| 3 | Redis database used to store cache data. | | group | 'auth' | Group which sub-node is attached to. |

cubic-core

| Core Option | Override | Description | |:------------- |:------------- |:------------- | | mongoUrl | 'mongodb://localhost/' | Base URL for mongodb connection. | | mongoDb | 'cubic-auth' | Mongodb database to use in endpoints by default | | apiUrl | 'http://localhost:3030' | API to serve requests on. | | authUrl | 'http://localhost:3030' | Auth server to authenticate on. (same as API) | | group | 'auth' | Group which sub-node is attached to. |

License

MIT