-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
689 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
--- | ||
title: Clients without dedicated backends | ||
hide_title: true | ||
--- | ||
|
||
# Clients Without Dedicated Backends | ||
|
||
You can use the following guide if you have frontend clients that use a separate domain for authentication but do not have dedicated backends for other functionalities. | ||
|
||
## 1. Set Up Your Authentication Portal | ||
|
||
First, initialize and setup **SuperTokens** according to the [quick setup guide](#). | ||
|
||
## 2. Initialize the OAuth2Provider | ||
|
||
In addition to the authentication recipes you’ve set up, initialize the OAuth2Provider recipe on your backend service. | ||
The default settings should be sufficient for most use cases. | ||
|
||
```typescript | ||
import supertokens from "supertokens-node"; | ||
import OAuth2Provider from"supertokens-node/recipe/oauth2"; | ||
|
||
supertokens.init({ | ||
framework: "express", | ||
supertokens: { | ||
connectionURI: "<YOUR_CONNECTION_URI>", | ||
apiKey: "<YOUR_API_KEY>", | ||
}, | ||
appInfo: { | ||
appName: "", | ||
apiDomain: "<YOUR_API_DOMAIN>", | ||
websiteDomain: "<YOUR_WEBSITE_DOMAIN>", | ||
apiBasePath: "/auth", | ||
websiteBasePath: "/auth" | ||
}, | ||
recipeList: [ | ||
// This is where you initialize the OAuth2 recipe | ||
// TODO: Show the config parameters here | ||
OAuth2Provider.init(), | ||
] | ||
}); | ||
``` | ||
|
||
## 3. Add a Way to Create OAuth2 Clients | ||
|
||
We have to create OAuth2 clients in order to allow them to authenticate through our flow. | ||
|
||
First we need to add a method to do this. | ||
Our recommendation is to use the `createClient` function that is exposed by our SDK. | ||
Alternatively, you can also directly call the **SuperTokens** core API. | ||
|
||
### Using the `createClient` function | ||
|
||
```typescript | ||
import { createClient } from "supertokens-node/recipe/oauth2"; | ||
|
||
createClient({ | ||
// This value will be shown in the auth page when the app requests the user to authenticate | ||
clientName: 'My Application', | ||
// TODO: Add info about this | ||
responseTypes: ['code', 'id_token'], | ||
// TODO: Add info about this | ||
grantTypes: ['authorization_code', 'refresh_token'], | ||
// TODO: Add info about this | ||
redirectUri: 'https://example.com/oauth/callback', | ||
}); | ||
|
||
``` | ||
|
||
### Using the Core API | ||
|
||
```bash | ||
## TODO: This is a dummy example. | ||
curl -X POST https://api.auth.example.com/oauth2/clients \ | ||
-H "Content-Type: application/json" \ | ||
-d '{ | ||
"client_name": "My Application", | ||
"response_types": ["code", "id_token"], | ||
"grant_types": ["authorization_code", "refresh_token"], | ||
"redirect_uris": ["https://different.com/oauth/callback"] | ||
}' | ||
``` | ||
|
||
## 4. Create Separate Clients for Each Application | ||
|
||
Using the method that we defined in the previous step create separate clients for each of your applications. | ||
|
||
Repeat the process for each domain, adjusting the `clientName` and `redirectUri` as necessary. | ||
|
||
|
||
## 5. Set Up Your Frontend and Integrate with an OIDC Library | ||
|
||
Integrate your frontend applications with a generic OAuth2 or OIDC library. Here are a few popular options: [oidc-client-js](https://github.com/IdentityModel/oidc-client-js), [openid-client](https://github.com/panva/node-openid-client) | ||
|
||
### Example Using `oidc-client-js` | ||
|
||
```html | ||
<!-- index.html --> | ||
<script src="https://cdn.jsdelivr.net/npm/oidc-client@latest/dist/oidc-client.min.js"></script> | ||
<script> | ||
const config = { | ||
authority: 'https://api.auth.example.com', | ||
client_id: 'YOUR_CLIENT_ID', | ||
redirect_uri: 'https://yourdomain.com/oauth/callback', | ||
response_type: 'code', | ||
scope: 'openid profile email', | ||
post_logout_redirect_uri: 'https://yourdomain.com/logout', | ||
}; | ||
const userManager = new Oidc.UserManager(config); | ||
// Handle login redirection | ||
function login() { | ||
userManager.signinRedirect(); | ||
} | ||
// Handle logout redirection | ||
function logout() { | ||
userManager.signoutRedirect(); | ||
} | ||
// Handle user session | ||
userManager.getUser().then(function (user) { | ||
if (user) { | ||
document.getElementById('user-info').innerText = `Hello, ${user.profile.name}`; | ||
} | ||
}); | ||
// Setup login button | ||
document.getElementById('login-button').addEventListener('click', login); | ||
document.getElementById('logout-button').addEventListener('click', logout); | ||
</script> | ||
|
||
<button id="login-button">Login with OAuth2</button> | ||
<button id="logout-button">Logout</button> | ||
<div id="user-info"></div> | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
--- | ||
title: Introduction | ||
hide_title: true | ||
--- | ||
|
||
# OAuth2 Support | ||
|
||
**OAuth2**, Open Authorization, is an industry-standard authorization framework that enables third-party applications to obtain limited access to a user's resources without exposing their credentials. | ||
It is commonly used for single sign-on (SSO) and authorization. | ||
|
||
## When to use OAuth2 | ||
|
||
In most cases, when using **SuperTokens**, you should not have to use OAuth2 directly. | ||
We already expose the `ThirdParty` recipe that enables users to login using external providers. | ||
This covers most of the authentication scenarios that involve OAuth2. | ||
|
||
However, there are some custom use cases where you will have to implement a different authentication flow. | ||
|
||
- **[If you have multiple frontends connecting to the same backend](/docs)** | ||
- **[If you want to have an unified login experience across multiple domains](/docs)** | ||
- **[If you want to reuse your website login for desktop and mobile apps](/docs)** | ||
- **[For Machine to Machine communication](/docs)** | ||
|
||
For these specific instances we expose an `OAuth` recipe that allows you to complete your setup. | ||
|
||
|
||
## OAuth2 Reference | ||
|
||
Before we explore our OAuth2 implementation let's first recap some common terms and concepts that are used in the framework. | ||
We will use them throughout the next pages. | ||
|
||
### Clients | ||
|
||
An OAuth 2.0 client is an application that interacts with an OAuth 2.0 provider to request access to a user's resources. | ||
It then utilizes the access tokens granted by the provider to perform authorized operations on behalf of the user. | ||
|
||
The term **client** does not imply any particular implementation characteristics (e.g. whether the application executes on a server, a desktop, or other devices). | ||
|
||
|
||
### Tokens | ||
|
||
An OAuth token is a credential used to access protected resources on behalf of a user. | ||
|
||
#### Access Token | ||
|
||
Access tokens are what the OAuth client uses to make requests to an API. The access token is meant to be read and validated by the API. | ||
|
||
#### ID Token | ||
|
||
An ID token contains information about what happened when a user authenticated, and is intended to be read by the OAuth client. | ||
The ID token may also contain information about the user such as their name or email address, although that is not a requirement of an ID token. | ||
|
||
#### Refresh Token | ||
|
||
An OAuth Refresh Token is a string that the OAuth client can use to get a new access token without the user's interaction. | ||
|
||
### Flows | ||
|
||
Flows are the set of steps a Client has to perform in order to obtain an access token. | ||
Our implementation supports the following grant types: | ||
- [Authorization Code](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.1) | ||
- [Implicit](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.2) | ||
- [Client credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.4) | ||
|
||
### Scopes | ||
|
||
Scopes in OAuth 2.0 specify the level of access an application is requesting from the user's resources. | ||
This way you can define the boundaries and permissions for what the access token can do. | ||
|
||
### PKCE | ||
|
||
PKCE (RFC 7636) is an extension to the Authorization Code flow to prevent CSRF and authorization code injection attacks. https://oauth.net/2/pkce/ | ||
We support PKCE and recommend that you use a library that makes use of it. | ||
You can opt-in by setting the code_challenge (and optionally code_challenge_method) parameters in the authorization URL and then verifying it after the user gets redirected back to the client. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
--- | ||
title: Machine to Machine Authentication | ||
hide_title: true | ||
--- | ||
|
||
# Machine to Machine Authentication | ||
|
||
You can use the following guide if you want to implement a custom authentication flow between your microservices. | ||
|
||
## 1. Set Up Your Authentication Portal | ||
|
||
First, initialize and setup **SuperTokens** according to the [quick setup guide](#). | ||
|
||
## 2. Initialize the OAuth2Provider | ||
|
||
In addition to the authentication recipes you’ve set up, initialize the OAuth2Provider recipe on your backend service. | ||
The default settings should be sufficient for most use cases. | ||
|
||
```typescript | ||
import supertokens from "supertokens-node"; | ||
import OAuth2Provider from"supertokens-node/recipe/oauth2"; | ||
|
||
supertokens.init({ | ||
framework: "express", | ||
supertokens: { | ||
connectionURI: "<YOUR_CONNECTION_URI>", | ||
apiKey: "<YOUR_API_KEY>", | ||
}, | ||
appInfo: { | ||
appName: "", | ||
apiDomain: "<YOUR_API_DOMAIN>", | ||
websiteDomain: "<YOUR_WEBSITE_DOMAIN>", | ||
apiBasePath: "/auth", | ||
websiteBasePath: "/auth" | ||
}, | ||
recipeList: [ | ||
// This is where you initialize the OAuth2 recipe | ||
// TODO: Show the config parameters here | ||
OAuth2Provider.init(), | ||
] | ||
}); | ||
``` | ||
|
||
## 3. Add a Way to Create OAuth2 Clients | ||
|
||
We have to create OAuth2 clients in order to allow them to authenticate through our flow. | ||
|
||
First we need to add a method to do this. | ||
Our recommendation is to use the `createClient` function that is exposed by our SDK. | ||
Alternatively, you can also directly call the **SuperTokens** core API. | ||
|
||
### Using the `createClient` function | ||
|
||
```typescript | ||
import { createClient } from "supertokens-node/recipe/oauth2"; | ||
|
||
createClient({ | ||
// This value will be shown in the auth page when the app requests the user to authenticate | ||
clientName: 'My Application', | ||
// TODO: Add info about this | ||
responseTypes: ['code', 'id_token'], | ||
// TODO: Add info about this | ||
grantTypes: ['client_credentials'], | ||
}); | ||
|
||
``` | ||
|
||
### Using the Core API | ||
|
||
```bash | ||
## TODO: This is a dummy example. | ||
curl -X POST https://api.auth.example.com/oauth2/clients \ | ||
-H "Content-Type: application/json" \ | ||
-d '{ | ||
"client_name": "My Application", | ||
"response_types": ["code", "id_token"], | ||
"grant_types": ["client_credentials"] | ||
}' | ||
``` | ||
|
||
## 4. Create Separate Clients for Each Application | ||
|
||
Using the method that we defined in the previous step create separate clients for each of your applications/microservices. | ||
|
||
Repeat the process for each domain, adjusting the `clientName`. | ||
|
||
## 5. How to Create Tokens | ||
|
||
To generate tokens for your microservices using the `client_credentials` grant type, use the following code snippet: | ||
|
||
```typescript | ||
const generateToken = async (client, scope) => { | ||
try { | ||
const res = await fetch('https://api.auth.example.com/auth/oauth/token', { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
client_id: client.clientId, | ||
client_secret: client.clientSecret, | ||
grant_type: 'client_credentials', | ||
scope, | ||
}), | ||
}); | ||
|
||
const tokenData = await res.json(); | ||
if (!res.ok) { | ||
throw new Error(`Error fetching token: ${tokenData.error_description}`); | ||
} | ||
|
||
console.log('Token created successfully:', tokenData); | ||
} catch (error) { | ||
console.error('Error creating token:', error); | ||
} | ||
}; | ||
|
||
// Example usage | ||
const client = { | ||
clientId: 'YOUR_CLIENT_ID', | ||
clientSecret: 'YOUR_CLIENT_SECRET', | ||
}; | ||
|
||
generateToken(client, 'your-desired-scope'); | ||
``` | ||
|
||
|
Oops, something went wrong.