Building A User Gallery with Auth0, Cloudinary and React
Tags: react, auth0, cloudinary, express
Published: 2021-10-16 14:07:41

---
title: Building A User Gallery with Auth0, Cloudinary and React
published: true
description: Using Auth0 and Cloudinary to build personal user galleries for users.
tags: react, auth0, cloudinary, express
//cover_image: https://miro.medium.com/max/3150/1*kofg5S-_kcyij3HL-uCnZA.png
---

We’ve all had our fair share of battling with authentication and authorization as developers. The case seems to be worse for frontend developers who don’t know how to spin up a server and can become hectic for most.

Enter Auth0, a tool that helps you integrate numerous authentication methods like Facebook, Twitter, Github, Microsoft, etc seamlessly into you frontend application. It can also be used on the backend as well.

Cloudinary, on the other hand, is a SaaS company that allows us to upload images and videos in a very easy way by providing us with an Upload Widget.

## Content

- Creating your Auth0 account and setting it up with the different authentication methods.
- Setting up Cloudinary.
- Tying it all together in our React App.

## Prerequisites

- You need to have a working understanding of Javascript, React and Express.
- You must have [Node](https://nodejs.org/en/download/) installed.

## Setting up Auth0

Head to the Auth0 Signup [page](https://auth0.com/signup?place=header&type=button&text=sign%20up). Select the Personal Account Type and leave the ‘I need advanced settings’ unchecked. Verify your account from your email once you’re done.

![Auth0 signup page](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633614218828_1.png)

On clicking next, you’d arrive on your Auth0 Dashboard. Click Applications to create one as we’ll need it to enable the Authentication for our app.

![Clicking applications tab](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633614698434_image.png)

Click on Create Application and a modal will pop up. Fill in your App Name and select Single Page Web Applications since we’re building in React.

![Creating the application](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633614845692_image.png)

After the App has been created, you’ll be asked to select which particular framework you’d be using. You can go ahead and select React. You’ll then be redirected to a page telling you how to set Auth0 up with React but we’d still go through it.

We need to get our **Domain** and **Client ID** so slide over to the **Settings** tab, copy them and paste them somewhere as we’d be needing them later.

![Copying the Domain and Client ID](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633615387979_image.png)

You also need to set **Token Endpoint Authentication Method** to **None** and set the **Application Type** to either **SPA**.

Finally, we have to set our **Callback URL**, **Logout URL** and **Allowed Web Origins.**

- **Callback URL** - It’s simply the URL that the user gets redirected to upon successful login.
- **Logout URL** - Like the above, it’s the URL the user gets redirected upon logging out. It must be specified in the logOut parameters also. ( More on this later in the article)
- **Allowed Web Origins** - We need to add the URL of our app here once again to enable Auth0 refresh its tokens.

For all, we can simply use our URL as http://localhost:3000 since we’re only testing locally. If you’re deploying it, just replace the URL with the URL of the deployed app.

Now, to set up our different authentication methods, click Social under the Authentication dropdown.

![Heading to the social tab](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633616395526_image.png)

By default, Google OAuth would be enabled for your app but with Development Keys. If the app is to be used in Production, be sure to change it to Production keys before deploying.

We’re going to be adding GitHub and Facebook as our possible sign-in options. Click on the Create Connection button and select GitHub.

![Selecting the social connections](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633616710073_image.png)

We need to get our Github App’s **Client ID** and **Client Secret** so open a new tab and head over [here](https://github.com/settings/developers) and go to the **OAuth Apps** tab. Click the **New OAuth App** button and fill in the details.

![Registering your Github OAuth App](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633617408274_image.png)

**Application Name** - Fill in anything of your choice.
**Homepage URL** - https://[YOUR_DOMAIN]
**Authorization Callback URL** - https://[YOUR_DOMAIN]/login/callback

Where YOUR_DOMAIN is the domain we got from Auth0 when setting up our app. Click Register Application, Generate your **Client Secret** on the next page and copy both your **Client Secret** and **Client ID**.

Head back to the Auth0 tab and paste them in their respective fields. Under Attributes, check ‘Email Address’ as we’ll be needing it.
On the next page, turn on the social connection for your application so you can make use of it.

![Turning on social connection for the application](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633618145120_image.png)

You can click on Try Connection to test it out. If it doesn’t work, try and go back and retrace where the mistake came from.

Go to the Social Connections page once again and Create a new Connection. This time, select Facebook.

Open a new tab, head over [here](https://developers.facebook.com/) and login to your Facebook account.
Click on **My Apps** in the navbar. The **App Type** should be **Consumer**
Enter the name you want to give the app and submit.

On your dashboard, Click the Set Up button on Facebook Login

![Facebook dashboard](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633618765715_image.png)

Click Web on the next page and enter your URL as https://[YOUR_DOMAIN]/login/callback. Hit Save and and go into the Settings Tab

![Settings tab](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633620266644_image.png)

As you can see atop the page, we need to get Advanced Access. Click on the Get Advanced Access Link. Click on Get Advanced for **public_profile** and **email**.

![Getting advanced access](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633620577192_image.png)

The page should look something like this when you’re done.

![Page after getting advanced access](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633621167346_image.png)

Head over to the Basic Tab of the Settings dropdown, copy your **App ID** as well as your **App Secret** and paste them in their respective fields on the Auth0 Facebook Connection Page. Tick the Checkbox of the email once again and Create the connection. Connect it to your App once again and we’re good to go.

Your social connections page should look something like this at this point.

![Social Connections Page](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633621977306_image.png)

---

## Setting Up Cloudinary

Signup for your Cloudinary account [here](https://cloudinary.com/users/register/free) and verify your email.

On getting to your account dashboard, all keys you need are displayed atop the page.

![Cloudinary dashboard](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633623622899_15.png)

You can leave the tab open cause we’re going to need some details later in the article. Click the Gear Icon on the navbar to go to the settings page. Go to the Upload tab and scroll down to upload presets. Click Enable unsigned uploading and an unsigned upload preset will automatically be added. Copy the preset name as we’ll need it later.

![Cloudinary upload presets](https://paper-attachments.dropbox.com/s_72736C8782453BBCEB18A1FA4C37415FF54B004A507D6E7409EC028D9C53DAA6_1633624729528_image.png)

## Tying it all together with our React App

Our React app is gonna be a user gallery where users come, sign in with Auth0 and their images get stored in the Cloudinary Account we’ve created. We need to fetch all images a user has uploaded also and to do this we need to pass our Cloudinary API Secret. Bear in mind that fetching an image through its url requires no authentication. Fetching the list of images of a user on the client side would be bad as attackers can go through our source code and figure out our API Secret at which point they’d have total access over our account. For this reason, we need to spin up a server.

### Spinning up the server

- Head over to this [repo](https://github.com/dro-1/user-gallery-be) and clone it locally.
- You need a .env file to store your keys so create one in the folder like so:

```js
   API_KEY="YOUR_API_KEY"
   API_SECRET="YOUR_API_SECRET"
   CLOUD_NAME="YOUR_CLOUD_NAME"
```
- Run the command below to install all packages required
  ```
   yarn
  ```

or
  ```
    npm install
  ```

depending on your package manager.

- Run this in your terminal to start the server.
  ```
   node app.js
  ```

You should get a response saying ‘Server connected on PORT 3001’

### Spinning up the React App

-  Clone the React App [here](https://github.com/dro-1/user-gallery).

-  Run the command below to install all packages required
```
   yarn
  ```

or
  ```
    npm install
  ```

depending on your package manager.

-  Open up the index.js file.

```js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { Auth0Provider } from "@auth0/auth0-react";
//import reportWebVitals from './reportWebVitals';
ReactDOM.render(
  <Auth0Provider
    domain={process.env.REACT_APP_DOMAIN}
    clientId={process.env.REACT_APP_CLIENT_ID}
    redirectUri="http://localhost:3000"
  >
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </Auth0Provider>,
  document.getElementById("root")
);  
```

To use Auth0 with React, we had to install the package ‘@auth0/auth0-react’. We’re simply setting up Auth0 with our app by passing it our **Domain** and **Client ID** which we got earlier. The **redirectUri** is the URL we’d like to redirect our users after they’re authenticated.

- Open up the _login.component.jsx_ file

```js
import React from "react";
import { useAuth0 } from "@auth0/auth0-react";
import "./login.css";
const LoginButton = () => {
  const { loginWithPopup, loginWithRedirect } = useAuth0();
  return <button onClick={() => loginWithPopup()}>Log In</button>;
};
const Login = () => {
  return (
    <div className="login container">
      <LoginButton />
    </div>
  );
};
export default Login;  
```

Here, we’re using the _useAuth0_ hook to get our login functions. We have loginWithPopup and loginWithRedirect which logs the user in through a popup and through redirecting to another page respectively as their name imply.

- Finally, we have the _home.component.jsx_ file

```js
import React, { useEffect, useRef, useState } from "react";
import { useAuth0 } from "@auth0/auth0-react";
import axios from "axios";
import "./home.css";
import Loader from "./../utils/loader.component";
const LogoutButton = () => {
  const { logout } = useAuth0();
  return (
    <button onClick={() => logout({ returnTo: window.location.origin })}>
      Log Out
    </button>
  );
};
const Home = () => {
  const { user } = useAuth0();
  const btnRef = useRef(null);
  const [images, setImages] = useState([]);
  console.log(user);
  const fetchImages = async () => {
    let { data } = await axios.get("http://localhost:3001/images");
    setImages((images) => [...images, ...data]);
  };
  const setUploadWidget = () => {
    var myWidget = window.cloudinary.createUploadWidget(
      {
        cloudName: process.env.REACT_APP_CLOUD_NAME,
        uploadPreset: process.env.REACT_APP_UPLOAD_PRESET,
        folder: user.email,
        tags: [user.email],
      },
      (error, result) => {
        if (!error && result && result.event === "success") {
          setImages((prevImages) => [...prevImages, result.info.secure_url]);
        }
      }
    );
    btnRef.current.addEventListener(
      "click",
      function () {
        myWidget.open();
      },
      false
    );
  };
  useEffect(() => {
    setUploadWidget();
    fetchImages();
  }, []);
  return (
    <div className="home">
      <header>
        <img src={user.picture} alt="" />
        <h2>Welcome, {user.name}</h2>
        <LogoutButton />
      </header>
      <button ref={btnRef} className="cloudinary-button">
        Upload files
      </button>
      <section>
        {images.length ? (
          images.map((image, index) => (
            <a
              href={image}
              key={index}
              target="_blank"
              rel="noopener noreferrer"
            >
              <img src={image} alt="Ronaldo" />
            </a>
          ))
        ) : (
          <Loader home />
        )}
      </section>
    </div>
  );
};
export default Home;  
```

First, we create our LogoutButton component which is based on the logout function gotten from the _useAuth0_ hook once again.

In our Home Component which is the main component, we have two main functions, the _fetchImages_ function, which fetch all images of the logged in user and the _setUploadWidget_ function which sets the upload widget to open up when the upload button is pressed.
We then call both functions in a _useEffect_ to ensure they are both called every time the page loads.

In the App.js file, we use _react-router-dom_ to enable different routes. We also create custom components _PrivateRoute_ and _PublicRoute_ to help redirect users who are not logged in to the login page and vice versa.

We also need another .env file for our environment variables.
  ```js
    REACT_APP_DOMAIN="YOUR_AUTH0_DOMAIN"
    REACT_APP_CLIENT_ID="YOUR_AUTH0_CLIENT_ID"
    REACT_APP_CLOUD_NAME="YOUR_CLOUDINARY_CLOUD_NAME"
  REACT_APP_UPLOAD_PRESET="YOUR_UNSIGNED_CLOUDINARY_UPLOAD_PRESET"
  ```

You can then go ahead and run
  ```
    yarn start
  ```

or
  ```
    npm start
  ```

to launch the project and everything should be working smoothly.

If you have any issues or want to contact me, you can reach me at [lorddro1532@gmail.com](mailto:lorddro1532@gmail.com) or on Twitter at [@the_dro_](https://twitter.com/the_dro_).

Content created for the [Hackmamba](https://content.hackmamba.io/) Jamstack Content Hackathon with [Auth0](https://auth0.com/) and [Cloudinary](https://cloudinary.com/).