Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
supertokens-node-mysql-ref-jwt-webservice
Advanced tools
![SuperTokens banner](https://raw.githubusercontent.com/supertokens/supertokens-logo/master/images/Artboard%20%E2%80%93%2027%402x.png)
This library implements a http service using which you can easily implement user session management for websites. For a complete solution, you also need to use the supertokens-website package on your frontend.
The library has the following features:
npm i --save supertokens-node-mysql-ref-jwt-webservice
Before you start using the service:
You will need to install MySQL and NodeJS in your system.
You will need to create a database in MySQL to store session info. This database can be either your already created DB or a new DB. This database name should be given as a config param to the library (See config section below).
There will be two tables created automatically for you in the provided database when you first use this library - if they don't already exist. If you want to create them yourself, you can do so with the following commands:
CREATE TABLE signing_key (
key_name VARCHAR(128),
key_value VARCHAR(255),
created_at_time BIGINT UNSIGNED,
PRIMARY KEY(key_name)
);
CREATE TABLE refresh_tokens (
session_handle_hash_1 VARCHAR(255) NOT NULL,
user_id VARCHAR(128) NOT NULL,
refresh_token_hash_2 VARCHAR(128) NOT NULL,
session_info TEXT,
expires_at BIGINT UNSIGNED NOT NULL,
jwt_user_payload TEXT,
PRIMARY KEY(session_handle_hash_1)
);
You can name these tables whatever you want, but be sure to send those to the library via the config params (see below).
Please make sure this service is only accessible by your systems and not by anyone outside.
As of now, this service is designed to work if your frontend is a website. To use this service, you will also need to use the supertokens-website in your frontend code. This library is a drop-in replacement for your axios/ajax calls on the frontend.
Together this service and the supertokens-website library take into account all the failures and race conditions that can possibly occur when implementing session management.
To start the server, go into the directory of this project and run:
node index.js <path to config.json file>
You can also use pm2 to run this service in a production setting. But be sure to pass a config.json file path to the node process.
To see the various config options, please click here
In the responses for the APIs below, I will be writing ... OR objA OR objB OR ...
This means the response will either be objA or objB, but not both.
API: /session
METHOD: POST
Input: {
userId: string, // unique ID for this user
jwtPayload: any, // any js object, array, or primitive type. Can also be undefined
sessionData: any // any js object, array, or primitive type. Can also be undefined
}
Output:
status code: 200
{
message: string,
status: "OK", // to understand the meaning of these status values, please see below
session: {
handle: string,
userId: string,
jwtPayload: any
},
accessToken: { value: string, expires: number }, // to be put in cookies as HttpOnly, secure and for all API paths
refreshToken: { value: string, expires: number }, // to be put in cookies as HttpOnly, secure and only for refresh API path
idRefreshToken: { value: string, expires: number }, // to be put in cookies as NOT HttpOnly, NOT secure and for all API paths
}
status code: 500 // something went wrong in the server
{ message: string }
status code: 400 // bad request
{ message: string }
API: /session
METHOD: PUT // this API may have a side effect of changing the access token. Hence it is PUT and not GET
Input: {
idRefreshToken: string OR undefined, // if this is undefined, then this API is going to throw UNAUTHORISED error anyways
accessToken: string,
}
Output:
status code: 200
{
message: string,
status: "OK",
session: {
handle: string,
userId: string,
jwtPayload: any
},
newAccessToken: { value: string, expires: number } OR undefined, // if this is not undefined, replace the current access token with this new one
} OR {
message: string,
status: "UNAUTHORISED" OR "TRY_REFRESH_TOKEN" // to understand the implications of these status codes, please see below.
}
status code: 500 // something went wrong in the server
{ message: string }
status code: 400 // bad request
{ message: string }
API: /refresh
METHOD: PUT
Input: {
idRefreshToken: string OR undefined, // if this is undefined, then this API is going to throw UNAUTHORISED error anyways
refreshToken: string,
}
Output:
status code: 200
{
message: string,
status: "OK",
session: {
handle: string,
userId: string,
jwtPayload: any
},
newAccessToken: { value: string, expires: number }, // replace existing access token with this
newRefreshToken: { value: string, expires: number }, // replace existing refresh token with this
newIdRefreshToken: { value: string, expires: number }, // replace existing idRefreshToken with this
} OR {
message: string,
status: "UNAUTHORISED"
sessionTheftDetected: {
value: false
} OR {
value: true, // here you can use the handle or the userId to destroy either this session, or all sessions belonging to this user
session: {
handle: string,
userId: string
}
}
}
status code: 500 // something went wrong in the server
{ message: string }
status code: 400 // bad request
{ message: string }
API: /session
METHOD: DELETE
Input: {
sessionHandle: string
}
Output:
status code: 200
{
message: string,
status: "OK",
deletedAnyEntry: boolean // will be false only if this session was missing in the db. This probably means it was removed earlier. In this case, you may not want to clear cookies for the client as they may have another live session already.
}
status code: 500 // something went wrong in the server
{ message: string }
status code: 400 // bad request
{ message: string }
API: /session/all
METHOD: DELETE
Input: {
userId: string
}
Output:
status code: 200
{
message: string,
status: "OK"
}
status code: 500 // something went wrong in the server
{ message: string }
status code: 400 // bad request
{ message: string }
This API does not synchronise with other processes calling this or the update session data API.
API: /session/data
METHOD: GET
Input: {
sessionHandle: string
}
Output:
status code: 200
{
message: string,
status: "OK",
sessionData: any
} OR {
message: string,
status: "UNAUTHORISED"
}
status code: 500 // something went wrong in the server
{ message: string }
status code: 400 // bad request
{ message: string }
This API does not synchronise with other processes calling this or the update session data API.
API: /session/data
METHOD: PUT
Input: {
sessionHandle: string,
sessionData: any
}
Output:
status code: 200
{
message: string,
status: "OK" OR "UNAUTHORISED"
}
status code: 500 // something went wrong in the server
{ message: string }
status code: 400 // bad request
{ message: string }
This is returned when the given session has expired. This can happen if the session does not exist in the DB, or the refresh token given has expired or is invalid. In this situation, you can clear the auth cookies for the client.
This is returned when the given access token is invalid or expired. This means that the session could still be alive, but we do not know yet. When this is returned, your frontend should query your refresh session API which should query the /refresh PUT
API of this service. If you are using supertokens-website on your frontend, then returning the status code that corresponds with session expiry will take care of this automatically. Also, you do not need to do anything with the cookies when this is returned.
The config file has to a be valid JSON file. It should have the following structure:
{
mysql: {
host?: string, // default localhost
port?: number, // default 3306
user: string, // If the tables in the database are not created already, then this user must have permission to create tables.
password: string,
connectionLimit?: number, // default 50
database: string, // name of the database to connect to. This must be created before running this package
tables?: {
signingKey?: string, // default signing_key - table name used to store secret keys
refreshTokens?: string // default refresh_token - table name used to store sessions
}
},
tokens?: {
accessToken?: {
signingKey?: {
dynamic?: boolean, // default true - if this is true, then the JWT signing key will change automatically every updateInterval hours.
updateInterval?: number, // in hours - default 24 - should be >= 1 && <= 720. How often to change the signing key
keyPath?: string // default undefined - If you want to give your own JWT signing key, please give the path here. If this is given, then the dynamic boolean will be ignored as key management will be up to you. The path should be either absolute, or relative to the folder you ran the node command in
},
validity?: number, // in seconds, default is 3600 seconds. should be >= 10 && <= 86400000 seconds. This determines the lifetime of an access token.
blacklisting?: boolean // default is false. If you set this to true, revoking a session will cause immediate invalidation of its access token, regardless of the token's lifetime. But know that this has an adverse effect on time effeciency of each getSession API call.
},
refreshToken?: {
validity?: number, // in hours, default is 2400 (100 days). This determines how long a refresh token is alive for. So if your user is inactive for these many hours, they will be logged out.
removalCronjobInterval?: string, // in the same style as of crontab, but with an extra seconds field as well. Default is "0 0 0 1-31/7 * *" - every 7th day of the month from 1 through 31. Defines how often the cronjob that removes expired sessions from the db should run.
}
},
port: number // port where to run service.
host: string // host where to run service.
}
You can play around with the demo project that uses the library this service is based on and the supertokens-website library. The demo demonstrates how this package behaves when it detects auth token theft (and the best part is that you are the attacker, muahahaha)!
This service is written in TypeScript (TS). When you make any changes to the .ts files in the /src/ts/* folder, run the following command in the /src folder to compile to .js:
tsc -p tsconfig.json
If you make any changes to index.ts in the root of this repo, once you compile it to .js, remember to change the import/export path from /src/ts/* to /src/build/* in the .js file.
We are most accessible via team@supertokens.io and via the GitHub issues feature. Please see this for more details
We have written a blog post about sessions in general:
To understand the logic behind how sessions are created, managed and destroyed, please refer to the WiKi section in supertokens-node-mysql-ref-jwt
Created with :heart: by the folks at SuperTokens. We are a startup passionate about security and solving software challenges in a way that's helpful for everyone! Please feel free to give us feedback at team@supertokens.io, until our website is ready :grinning:
FAQs
![SuperTokens banner](https://raw.githubusercontent.com/supertokens/supertokens-logo/master/images/Artboard%20%E2%80%93%2027%402x.png)
The npm package supertokens-node-mysql-ref-jwt-webservice receives a total of 0 weekly downloads. As such, supertokens-node-mysql-ref-jwt-webservice popularity was classified as not popular.
We found that supertokens-node-mysql-ref-jwt-webservice demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.