Skip to content

Implement user login

log in is how users access your application after verifying their identity. For B2B applications, log in involves additional complexity as users may belong to multiple organizations and each organization may have different authentication requirements.

Here are some common log in use cases:

  • Multiple authentication methods: Users can choose different authentication methods to log in, such as passwordless, their choice of social login, or enterprise SSO.
  • Organization-enforced policies: Organization administrators can enforce log in policies, such as requiring specific authentication method for certain users or authenticating users through their identity provider.
  • Cross-organization access: A user can log in to access multiple organizations or workspaces within your application.
  • Invitation-based access: A user signs in for the first time after accepting an email invitation to join an organization.
  • Enterprise SSO integration: Users authenticate through their corporate identity provider (e.g., Okta, Azure AD) instead of traditional username/password.

Scalekit helps you implement all such signup flows while handling the complexity of user management and authentication.

Let’s get started!

  1. npm install @scalekit-sdk/node

    Copy your API credentials from the Scalekit dashboard’s API Config section and set them as environment variables.

    Terminal window
    SCALEKIT_ENVIRONMENT_URL='<YOUR_ENVIRONMENT_URL>'
    SCALEKIT_CLIENT_ID='<ENVIRONMENT_CLIENT_ID>'
    SCALEKIT_CLIENT_SECRET='<ENVIRONMENT_CLIENT_SECRET>'

    Create a new Scalekit client instance.

    utils/auth.js
    import { Scalekit } from '@scalekit-sdk/node';
    export let scalekit = new Scalekit(
    process.env.SCALEKIT_ENVIRONMENT_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET
    );
  2. Generate the authorization URL to redirect users to the Scalekit-hosted login page. To get a refreshToken for session management, ensure you include offline_access in the scopes.

    Express.js
    const redirectUri = 'http://localhost:3000/api/callback';
    const options = {
    scopes: ['openid', 'profile', 'email', 'offline_access'],
    };
    const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options);
    res.redirect(authorizationUrl);

    This will redirect the user to Scalekit’s hosted sign-in page.

  3. Users can now log in using their preferred method. Scalekit handles the authentication details based on your configuration.

  4. After identity verification, Scalekit triggers a callback to your redirect_uri with an authorization code. Exchange this code to get the user’s profile.

    import scalekit from '@/utils/auth.js'
    const redirectUri = 'http://localhost:3000/api/callback';
    // Get the authorization code from the scalekit initiated callback
    app.get('/api/callback', async (req, res) => {
    const { code, error, error_description } = req.query;
    if (error) {
    return res.status(401).json({ error, error_description });
    }
    try {
    // Exchange the authorization code for a user profile
    const authResult = await scalekit.authenticateWithCode(
    code, redirectUri
    );
    const { user } = authResult;
    // "user" object contains the user's profile information
    // Next step: Create a session and log in the user
    5 collapsed lines
    res.redirect('/dashboard/profile');
    } catch (err) {
    console.error('Error exchanging code:', err);
    res.status(500).json({ error: 'Failed to authenticate user' });
    }
    });

    The authResult contains the user’s profile and the necessary tokens to create a session.

  5. With the user’s identity verified, you can now establish a session. This typically involves storing the tokens securely and using them to manage the user’s authenticated state.

    const { accessToken, refreshToken, expiresIn } = authResult;
    // Store the refreshToken securely, e.g., in a database
    await db.saveRefreshToken(user.id, refreshToken);
    // Set the accessToken as a secure, HTTP-only cookie
    res.cookie('accessToken', accessToken, {
    maxAge: (expiresIn - 60) * 1000,
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'strict'
    });

You have successfully implemented the login flow. Now you can: