authorize

Sometimes, such as to complete an auth flow, you need to show a page in its own new window (that may be separate browser tab or window on desktop, and embedded browser in mobile app). This is usually because auth pages (for security reasons) cannot be displayed inside of iframes.

For such cases, Web SDK provides the authorize function that simplifies the process of OAuth for addons.

OAuth flow overview:

  • An addon makes a call to the authorize function passing either a string (OAuth URL) or a function that returns the OAuth URL.
  • The application opens a new browser window that navigates to the OAuth URL.
  • After the user authenticates with the OAuth provider, they are redirected to the addon's callback endpoint (on the addon's domain).
  • The addon's server callback exchanges the authorization code for an access token and redirects to an HTML callback page with the token and state as URL parameters.
  • The HTML callback page loads the Web SDK and calls window.handleOAuthCallback(). The SDK automatically handles token delivery via postMessage (web) or deep link (mobile).
  • The application receives the token, returns it from the authorize function, and closes the OAuth window. The token is never sent to the application server, transmission happens entirely in the browser.
  • The authentication flow is complete, and the addon now has the access token.

The authorize function accepts either:

  • A string: The complete OAuth authorization URL
  • A function: Returns the OAuth authorization URL (useful if you need to generate the URL dynamically)

Your addon's server callback endpoint must redirect to an HTML page with the token passed as a URL parameter (e.g., ?token=...&state=...). The HTML page should load the Web SDK and call window.handleOAuthCallback(), which automatically handles token delivery for both web (postMessage) and mobile (deep link) platforms. The token is never sent to the application server; transmission happens entirely in the browser.

context.authorize(authUrl) Initiates the OAuth authorization flow and returns an access token for the user. The OAuth page is opened in a new browser window (or embedded browser on mobile). Your callback page must load the Web SDK and call window.handleOAuthCallback() to complete the flow. The SDK automatically handles token delivery for both web (via postMessage) and mobile (via deep link) platforms. The token is never sent to the application server.

Arguments
argumentTypeDescription
authUrlrequiredstring | (() => string)Either a string containing the OAuth authorization URL, or a function that returns the OAuth authorization URL. Your addon's server callback endpoint should exchange the authorization code for an access token, then redirect to an HTML page with the token as a URL parameter (e.g., ?token=xxx&state=xxx). The HTML page must load the Web SDK (https://files.kaiten.ru/web-sdk/v1.min.js) and call window.handleOAuthCallback() to complete the OAuth flow.

Return value - Promise<string>

// --- Addon scope: ---

// OPTION 1: Pass OAuth URL as a string
const authUrl = 'https://oauth.yandex.com/authorize?response_type=code&client_id=XXX&redirect_uri=https://my-addon.example.com/oauth-callback';
const token = await buttonContext.authorize(authUrl);

// OPTION 2: Pass a function that generates the OAuth URL
const makeAuthUrl = () => {
  const params = new URLSearchParams({
    response_type: 'code',
    client_id: 'YANDEX_CLIENT_ID',
    redirect_uri: 'https://my-addon.example.com/oauth-callback',
    state: JSON.stringify({ myData: 'value' }), // Optional: SDK merges this with platform info
  });
  return 'https://oauth.yandex.com/authorize?' + params.toString();
};

// Usage inside Addon.initialize (minimal card_buttons example):
Addon.initialize({
  card_buttons: async (cardButtonsContext) => [
    {
      text: 'Authorize with Yandex',
      callback: async (buttonContext) => {
        try {
          // Opens OAuth page in new browser window (or embedded browser on mobile)
          const token = await buttonContext.authorize(makeAuthUrl);
          // Use the token as needed
        } catch (error) {
          buttonContext.showSnackbar('Unable to authorize with Yandex.Disk', 'error');
        }
      }
    }
  ]
});

// --- Server callback scope (Express.js): ---
// This endpoint handles the OAuth provider's redirect to your addon's domain
const express = require('express');
const axios = require('axios');
const app = express();

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

  if (!code) {
    return res.redirect('/oauth-callback-complete?error=' + encodeURIComponent('Missing authorization code'));
  }

  try {
    // Exchange authorization code for access token
    const response = await axios.post('https://oauth.yandex.ru/token', new URLSearchParams({
      grant_type: 'authorization_code',
      code,
      client_id: 'YANDEX_CLIENT_ID',
      client_secret: 'YANDEX_CLIENT_SECRET',
      redirect_uri: 'https://my-addon.example.com/oauth-callback',
    }).toString(), {
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    });

    const token = response.data.access_token;

    // Redirect to callback page with token and state as URL parameters
    const callbackUrl = '/oauth-callback-complete?' + new URLSearchParams({
      token: token,
      state: state || '',
    }).toString();

    return res.redirect(callbackUrl);
  } catch (error) {
    console.error('OAuth token exchange failed:', error);
    return res.redirect('/oauth-callback-complete?error=' + encodeURIComponent('Failed to obtain access token'));
  }
});

// --- OAuth Callback Page: ---
// Serve this HTML page at /oauth-callback-complete

app.get('/oauth-callback-complete', (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>Authorization Complete</title>
      <script src="https://files.kaiten.ru/web-sdk/v1.min.js"></script>
    </head>
    <body>
      <p>Authorization complete. You can close this window.</p>
      <script>
        // Call SDK's OAuth callback handler
        // Automatically handles web (postMessage) and mobile (deep link) platforms
        window.handleOAuthCallback();
      </script>
    </body>
    </html>
  `);
});
logo
Kaiten
If you have any questions or need help with integration feel free to write us at support@kaiten.io