Login with Moon

Using Moon OAuth2 Provider for Authentication

OAuth 2.0 is a widely-used authorization framework that allows users to grant third-party applications limited access to their resources without sharing their login credentials. Moon, a platform, supports OAuth 2.0 for user authentication. This guide will walk you through the process of implementing OAuth 2.0 into a Moon-integrated app.

The implementation process involves four main steps:

Step 1: Grab Environment Variables from Moon

To begin, visit Moon's documentation or support page to obtain the necessary environment variables. Add these variables to your project's .env file. Below is an example of the variables your .env file should include:

NODE_PORT=4000
REACT_APP_CLIENT_ID=your_client_id
REACT_APP_CLIENT_SECRET=your_client_secret
REACT_APP_RESPONSE_TYPE=code
REACT_APP_REDIRECT_URI=http://example.com/authorize
REACT_APP_SCOPE=
REACT_APP_STATE=
NODE_GRANT_TYPE=authorization_code

Step 2: Initiate the Authentication Process

To start the authentication process, redirect the user to Moon's OAuth 2.0 authorization page. This can be done by triggering a redirect from your application's login interface. Use the environment variables obtained in the previous step to construct the redirect URL.

Here's an example of how to implement this in a React component:

// LoginButton.tsx
import React from 'react';

function LoginButton() {
  const handleClick = () => {
    const {
      REACT_APP_RESPONSE_TYPE,
      REACT_APP_CLIENT_ID,
      REACT_APP_REDIRECT_URI,
      REACT_APP_SCOPE,
      REACT_APP_STATE,
    } = process.env;

    const redirectUrl = `https://dash.usemoon.ai/authorize?response_type=${REACT_APP_RESPONSE_TYPE}&client_id=${REACT_APP_CLIENT_ID}&redirect_uri=${REACT_APP_REDIRECT_URI}&scope=${REACT_APP_SCOPE}&state=${REACT_APP_STATE}`;

    window.location.href = redirectUrl;
  };

  return <button onClick={handleClick}>Login with Moon</button>;
}

export default LoginButton;

Step 3: Handle the Redirect from the Authorization Server

After the user logs in to Moon's separate login page and authorizes the application, they will be redirected back to your application to the URI specified by redirect_uri. Your application needs to handle this redirection and extract the authorization code from the URL.

Here's an example of how to implement this in a React component:

// OAuth2Callback.ts
import React, { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { useMoonSDK } from '@moonup/react';

function OAuth2Callback() {
  const location = useLocation();
  const { moon } = useMoonSDK();

  useEffect(() => {
    const fetchData = async () => {
      // Extract the 'code' parameter from the URL query string.
      const urlParams = new URLSearchParams(location.search);
      const code = urlParams.get('code');

      if (code) {
        // Use the authorization code to request an access token.
        try {
          const response = await fetch(`http://localhost:4000/callback?code=${code}`, {
            headers: { 'Content-Type': 'application/json' },
          });
          const data = await response.json();

          // Set the access token in the client application for making authenticated requests.
          moon?.setAccessToken(data.access_token, data.refresh_token);
        } catch (error) {
          console.error('Authentication error:', error);
        }
      }
    };

    fetchData();
  }, [location, moon]);

  return <div>Processing OAuth2 callback...</div>;
}

export default OAuth2Callback;

Step 4: Exchange the Authorization Code for an Access Token

The final step involves exchanging the authorization code for an access token. This step is typically performed by the backend server to keep the client secret confidential.

Here's an example of how to implement this in a Node.js server:

// server/index.ts
import express, { Request, Response } from 'express';
import axios from 'axios';

const app = express();

app.get('/callback', async (req: Request, res: Response) => {
  try {
    const { code, state } = req.query;
    const {
      REACT_APP_GRANT_TYPE,
      REACT_APP_CLIENT_ID,
      REACT_APP_CLIENT_SECRET,
      REACT_APP_REDIRECT_URI,
    } = process.env;

    const response = await axios.post(
      'https://dash.usemoon.ai/api/oauth2/exchange',
      {
        grant_type: REACT_APP_GRANT_TYPE,
        code: code,
        client_id: REACT_APP_CLIENT_ID,
        client_secret: REACT_APP_CLIENT_SECRET,
        redirect_uri: REACT_APP_REDIRECT_URI,
      },
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
        },
      }
    );

    res.cookie('sb-api-auth-token', response.data);
    res.json(response.data);
  } catch (error) {
    console.error('Server error:', error);
    return res.status(500).json({
      error: 'Server error. Try again with a different prompt.',
      success: false,
    });
  }
});

app.listen(process.env.NODE_PORT, () => {
  console.log(`Server is running on port ${process.env.NODE_PORT}`);
});

By following these steps, you can successfully implement OAuth 2.0 authentication using Moon in your application.

Last updated