Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
simple-oauth2
Advanced tools
The simple-oauth2 npm package is a straightforward and flexible library for implementing OAuth2 authentication in Node.js applications. It provides a simple API to handle the OAuth2 authorization flows, including obtaining access tokens, refreshing tokens, and revoking tokens.
Authorization Code Flow
This feature allows you to generate an authorization URL for the Authorization Code Flow. Users can visit this URL to authorize your application and obtain an authorization code.
const { AuthorizationCode } = require('simple-oauth2');
const client = new AuthorizationCode({
client: {
id: 'your-client-id',
secret: 'your-client-secret',
},
auth: {
tokenHost: 'https://authorization-server.com',
tokenPath: '/oauth/token',
authorizePath: '/oauth/authorize',
},
});
const authorizationUri = client.authorizeURL({
redirect_uri: 'http://localhost:3000/callback',
scope: 'user_profile',
state: 'random-string',
});
console.log('Visit this URL to authorize:', authorizationUri);
Obtaining Access Token
This feature allows you to exchange an authorization code for an access token. The access token can then be used to access protected resources on behalf of the user.
const tokenParams = {
code: 'authorization-code',
redirect_uri: 'http://localhost:3000/callback',
scope: 'user_profile',
};
client.getToken(tokenParams)
.then((result) => {
const accessToken = client.createToken(result);
console.log('Access Token:', accessToken.token);
})
.catch((error) => {
console.error('Access Token Error', error.message);
});
Refreshing Access Token
This feature allows you to refresh an expired access token using a refresh token. The new access token can then be used to continue accessing protected resources.
const token = client.createToken({
access_token: 'existing-access-token',
refresh_token: 'existing-refresh-token',
expires_in: '3600',
});
token.refresh()
.then((result) => {
const refreshedToken = client.createToken(result);
console.log('Refreshed Token:', refreshedToken.token);
})
.catch((error) => {
console.error('Refresh Token Error', error.message);
});
Revoking Access Token
This feature allows you to revoke an access token, making it invalid for further use. This is useful for logging out users or invalidating tokens for security reasons.
const token = client.createToken({
access_token: 'existing-access-token',
refresh_token: 'existing-refresh-token',
expires_in: '3600',
});
token.revoke('access_token')
.then(() => {
console.log('Access Token Revoked');
})
.catch((error) => {
console.error('Revoke Token Error', error.message);
});
passport-oauth2 is a strategy for the Passport authentication middleware that implements OAuth 2.0. It is highly configurable and can be used with various OAuth 2.0 providers. Compared to simple-oauth2, passport-oauth2 is more integrated with the Passport ecosystem, making it a good choice if you are already using Passport for authentication.
client-oauth2 is a lightweight and flexible library for OAuth 2.0 in JavaScript. It supports multiple OAuth 2.0 flows and is easy to use in both Node.js and browser environments. Compared to simple-oauth2, client-oauth2 offers a more minimalistic approach and can be a good choice for developers looking for a smaller library.
axios-oauth-client is a library that integrates OAuth 2.0 with the popular Axios HTTP client. It simplifies the process of making authenticated HTTP requests using OAuth 2.0 tokens. Compared to simple-oauth2, axios-oauth-client is more focused on integrating OAuth 2.0 with Axios, making it a good choice if you are already using Axios for HTTP requests.
Simple OAuth2 is a Node.js client library for the OAuth 2.0 authorization framework. OAuth 2.0 is the industry-standard protocol for authorization, enabling third-party applications to obtain limited access to an HTTP service, either on behalf of a resource owner or by allowing the third-party application to obtain access on its own behalf.
Version | Node support |
---|---|
5.x | Node 14.x or higher |
6.x (Development) | Node 16.x or higher |
Older node versions are unsupported.
Install the client library using npm:
npm install --save simple-oauth2
With a minimal configuration, create a client instance of any supported grant type.
const config = {
client: {
id: '<client-id>',
secret: '<client-secret>'
},
auth: {
tokenHost: 'https://api.oauth.com'
}
};
const { ClientCredentials, ResourceOwnerPassword, AuthorizationCode } = require('simple-oauth2');
For a complete reference of configuration options, see the API Options
Depending on your use-case, any of the following supported grant types may be useful:
The Authorization Code grant type is used by confidential and public clients to exchange an authorization code for an access token. After the user returns to the client via the redirect URL, the application will get the authorization code from the URL and use it to request an access token.
async function run() {
const client = new AuthorizationCode(config);
const authorizationUri = client.authorizeURL({
redirect_uri: 'http://localhost:3000/callback',
scope: '<scope>',
state: '<state>',
customParam: 'foo', // non-standard oauth params may be passed as well
});
// Redirect example using Express (see http://expressjs.com/api.html#res.redirect)
res.redirect(authorizationUri);
const tokenParams = {
code: '<code>',
redirect_uri: 'http://localhost:3000/callback',
scope: '<scope>',
};
try {
const accessToken = await client.getToken(tokenParams);
} catch (error) {
console.log('Access Token Error', error.message);
}
}
run();
See the API reference for a complete reference of available options or any of our available examples at the example folder.
The Resource Owner Password Credentials grant type is a way to exchange a user's credentials for an access token. Because the client application has to collect the user's password and send it to the authorization server, it is not recommended that this grant be used at all anymore.
async function run() {
const client = new ResourceOwnerPassword(config);
const tokenParams = {
username: 'username',
password: 'password',
scope: '<scope>',
};
try {
const accessToken = await client.getToken(tokenParams);
} catch (error) {
console.log('Access Token Error', error.message);
}
}
run();
See the API reference for a complete reference of available options.
The Client Credentials grant type is used by clients to obtain an access token outside of the context of a user. This is typically used by clients to access resources about themselves rather than to access a user's resources.
async function run() {
const client = new ClientCredentials(config);
const tokenParams = {
scope: '<scope>',
};
try {
const accessToken = await client.getToken(tokenParams);
} catch (error) {
console.log('Access Token error', error.message);
}
}
run();
See the API reference for a complete reference of available options.
On completion of any supported grant type an access token will be obtained. A list of supported operations can be found below.
On long lived applications, it is often necessary to refresh access tokens. In such scenarios the access token is usually persisted in an external database by first serializing it.
async function run() {
const accessTokenJSONString = JSON.stringify(accessToken);
await persistAccessTokenJSON(accessTokenJSONString);
}
run();
By the time we need to refresh the persistent access token, we can get back an AccessToken instance by using the client's .createToken method.
async function run() {
const accessTokenJSONString = await getPersistedAccessTokenJSON();
let accessToken = client.createToken(JSON.parse(accessTokenJSONString));
}
run();
Once we have determined the access token needs refreshing with the .expired() method, we can finally refresh it with a .refresh() method call.
async function run() {
if (accessToken.expired()) {
try {
const refreshParams = {
scope: '<scope>',
};
accessToken = await accessToken.refresh(refreshParams);
} catch (error) {
console.log('Error refreshing access token: ', error.message);
}
}
}
run();
The .expired() helper is useful for knowing when a token has definitively expired. However, there is a common race condition when tokens are near expiring. If an OAuth 2.0 token is issued with a expires_in
property (as opposed to an expires_at
property), there can be discrepancies between the time the OAuth 2.0 server issues the access token and when it is received.
These come down to factors such as network and processing latency and can be worked around by preemptively refreshing the access token:
async function run() {
const EXPIRATION_WINDOW_IN_SECONDS = 300; // Window of time before the actual expiration to refresh the token
if (accessToken.expired(EXPIRATION_WINDOW_IN_SECONDS)) {
try {
accessToken = await accessToken.refresh();
} catch (error) {
console.log('Error refreshing access token: ', error.message);
}
}
}
run();
Warning: Tokens obtained with the Client Credentials grant may not be refreshed. Fetch a new token when it's expired.
See the API reference for a complete reference of available options.
When you've done with the token or you want to log out, you can revoke both access and refresh tokens.
async function run() {
try {
await accessToken.revoke('access_token');
await accessToken.revoke('refresh_token');
} catch (error) {
console.log('Error revoking token: ', error.message);
}
}
run();
As a convenience method, you can also revoke both tokens in a single call:
async function run() {
try {
// Revokes both tokens, refresh token is only revoked if the access_token is properly revoked
await accessToken.revokeAll();
} catch (error) {
console.log('Error revoking token: ', error.message);
}
}
run();
See the API reference for a complete reference of available options.
Whenever a client or server error is produced, a boom error is thrown by the library. As such any boom error property is available, but the exact information may vary according to the type of error.
async function run() {
const client = new ClientCredentials(config);
try {
await client.getToken();
} catch(error) {
console.log(error.output);
}
}
run();
// { statusCode: 401,
// payload:
// { statusCode: 401,
// error: 'Unauthorized',
// message: 'Response Error: 401 Unauthorized' },
// headers: {} }
This module uses the debug module to help on error diagnosis. Use the following environment variable to help in your debug journey:
DEBUG=*simple-oauth2*
See CONTRIBUTING
Special thanks to the following people for submitting patches.
See CHANGELOG
Simple OAuth 2.0 is licensed under the Apache License, Version 2.0
Simple OAuth 2.0 come to life thanks to the work I've made in Lelylan, an open source microservices architecture for the Internet of Things. If this project helped you in any way, think about giving us a star on Github.
5.1.0
FAQs
Node.js client for OAuth2
The npm package simple-oauth2 receives a total of 202,164 weekly downloads. As such, simple-oauth2 popularity was classified as popular.
We found that simple-oauth2 demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers 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.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.