Skip to main content

Authentication with OAuth

Implementing OAuth authentication is essential to obtain an Access Token and be able to use the APIs. Follow the steps in this guide to understand the OAuth process and integrate it correctly into your application.

  1. Understand the concept of OAuth: OAuth is a standard protocol that lets you securely delegate the authentication of a user to a third-party service. The process involves three main actors: the client (your application), the authorization server (Riseact Account) and the resource server (Riseact Core, which provides access to the APIs). OAuth ensures that the client obtains a valid Access Token to access the resources protected by the server on behalf of the organization that installs the application.

  2. Register your application: Before implementing OAuth authentication, you need to register your application on Riseact Partners to obtain the required credentials. These credentials include a Client ID and a Client Secret, which will be used to identify and authenticate your application during the authorization process.

  3. Configure authentication in your backend: In your backend, you'll need to implement the logic to handle the OAuth authorization flow. This involves creating an authorization endpoint that will redirect the user to the authorization server for authentication. During this phase, you'll need to include your Client ID, generate the PKCE keys (code_verifier and code_challenge) and a random state value for CSRF protection. You'll need to temporarily save both the code_verifier and the state in order to verify them in the callback. When an organization installs your application on Riseact, an iframe pointing to the app URL you provided at registration time will be shown in the admin panel. Along with the URL you provided, an __organization parameter will be passed that you can use to identify the organization using your application and skip the organization-selection roundtrip on Riseact Admin. To do so, you'll need to redirect the user to the authorization server with an __organization parameter containing the slug of the organization you received from the __organization parameter of the redirect URL.

Here's an example in node.js:

app.get('/oauth/authorize', (req, res) => {
const { codeChallenge, codeVerifier } = generatePkceKeys();
const state = crypto.randomBytes(16).toString('hex');

// Salva codeVerifier e state come preferisci. In questo caso utilizziamo un database
db.savePkceSession(state, { codeVerifier });

const params = {
client_id: CLIENT_ID,
redirect_uri: 'https://your-app.com/oauth/callback',
response_type: 'code',
code_challenge_method: 'S256',
code_challenge: codeChallenge,
state,
__organization: req.query.__organization,
};

res.redirect(`https://accounts.riseact.org/oauth/authorize/?${qs.stringify(params)}`);
});

Example of the call with curl:

curl -X GET \
"https://accounts.riseact.org/oauth/authorize/\
?client_id=CLIENT_ID\
&redirect_uri=https://your-app.com/oauth/callback\
&response_type=code\
&code_challenge_method=S256\
&code_challenge=YOUR_CODE_CHALLENGE\
&state=YOUR_RANDOM_STATE\
&__organization=YOUR_ORGANIZATION"
  1. Handle the callback redirect: After the user has successfully authenticated with the authorization server, they will be redirected to your application via a callback URL specified in the previous step. If the URL doesn't match one of those authorized at registration time, the request will fail. Your backend will need to handle this redirect, verify that the received state parameter matches the one saved earlier (CSRF protection), and retrieve the associated code_verifier. Using the authorization code received and the code_verifier, make a request to the authorization server to obtain an Access Token.

Here's an example in node.js:

app.get('/oauth/callback', async (req, res) => {
const { code, state } = req.query;

// Recupera la sessione PKCE dal database usando lo state come chiave
const session = await db.getPkceSession(state);

if (!session) {
return res.status(400).send('Invalid state');
}

const formData = {
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
grant_type: 'authorization_code',
code,
redirect_uri: 'https://your-app.com/oauth/callback',
code_verifier: session.codeVerifier,
};

const { data } = await axios.post('https://accounts.riseact.org/oauth/token/', qs.stringify(formData), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});

// Salva le credenziali ottenute come preferisci. In questo caso utilizziamo un database
db.saveCredentials(data.access_token, data.refresh_token, data.expires_in);
});

Example of the call with curl:

curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "grant_type=authorization_code" \
-d "code=YOUR_CODE" \
-d "redirect_uri=https://your-app.com/oauth/callback" \
-d "code_verifier=YOUR_CODE_VERIFIER" \
https://accounts.riseact.org/oauth/token/
  1. Use the Access Token to access the organization's protected resources: Whenever you want to access the resources protected by the APIs, you'll need to include the Access Token in your request in the Authorization header. The APIs will use the Access Token to verify the authenticity of the request and provide the requested resources only if the Access Token is valid.

Here's an example in node.js:

const { data } = await axios.get('https://core.riseact.org/admin/graphql/', {
headers: {
Authorization: `Bearer ${access_token}`,
},
});

Example of the call with curl:

curl -X GET \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
https://core.riseact.org/admin/graphql/
  1. Handle Access Token renewal: Access Tokens have a limited lifetime. To ensure a seamless user experience, you'll need to implement the logic to automatically renew the Access Token before it expires. This can be done using the Access Token refresh process provided by the authorization server.

Here's an example in node.js:

app.get('/oauth/refresh', async (req, res) => {
const { refresh_token } = req.query;

const formData = {
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
grant_type: 'refresh_token',
refresh_token,
};

const { data } = await axios.post('https://accounts.riseact.org/oauth/token/', qs.stringify(formData), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});

// Salva le credenziali ottenute come preferisci. In questo caso utilizziamo un database
db.saveCredentials(data.access_token, data.refresh_token, data.expires_in);
});

Example of the call with curl:

curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "grant_type=refresh_token" \
-d "refresh_token=YOUR_REFRESH_TOKEN" \
https://accounts.riseact.org/oauth/token/

By correctly implementing OAuth authentication in your application, you'll be able to obtain a valid Access Token and access the protected resources through the APIs. Make sure to follow the specifications and documentation provided by Riseact for a correct and secure implementation. Happy implementing!