# User Authentication

Let's configure the authentication service needed to authenticate users in your app. As mentioned in the previous steps, we are employing [Auth0](https://auth0.com/) (sign up for a free account [here](https://auth0.com/signup)).  Next, setup an Auth0 client app and API so that Auth0 can interface with your app.

## Setup a Client App

1. Go to the [Auth0 Dashboard](https://manage.auth0.com/#/) and click the [create a new client](https://manage.auth0.com/#/clients/create) button.
2. Give your app a name and select **Single Page Web Applications**.
3. In the **Settings** for your new Auth0 client app, add `http://localhost:3000/callback` to the **Allowed Callback URLs**.

![1.](http://res.cloudinary.com/unicodeveloper/image/upload/v1521709147/newclient.png)

*Create a new client*

## Setup an API

Go to [APIs](https://manage.auth0.com/#/apis) in your Auth0 dashboard and click on the **Create API** button. Enter a name for the API. Set the **Identifier** to your API endpoint URL. In this example, this is `http://localhost:3001/api`. The **Signing Algorithm** should be `RS256`.

![Create API button](http://res.cloudinary.com/unicodeveloper/image/upload/v1521709936/create_api.png)

*Create a new API*

![New API Dialog](http://res.cloudinary.com/unicodeveloper/image/upload/v1521709861/newapibox.png)

*New API Dialog*

You're now ready to implement Auth0 authentication in your app.

> **Info** **Note:** As we want the best security available, we are going to rely on the [Auth0 login page](https://auth0.com/docs/hosted-pages/login). This method consists of redirecting users to a login page hosted by Auth0 that is easily customizable right from the [Dashboard](https://manage.auth0.com/).

Navigate to your `src` directory and create a `utils` folder. In the `utils` folder, create a file, **AuthService.js** and add this code to it.

```
import decode from 'jwt-decode';
import { browserHistory } from 'react-router';
import auth0 from 'auth0-js';
const ID_TOKEN_KEY = 'id_token';
const ACCESS_TOKEN_KEY = 'access_token';

const CLIENT_ID = 'xxxxxxxxxxxxxx';
const CLIENT_DOMAIN = 'xxxxxxxxxx';
const REDIRECT = 'https://localhost:3000/callback';
const SCOPE = 'full:access';
const AUDIENCE = 'http://localhost:3001/api';

var auth = new auth0.WebAuth({
  clientID: CLIENT_ID,
  domain: CLIENT_DOMAIN
});

export function login() {
  auth.authorize({
    responseType: 'token id_token',
    redirectUri: REDIRECT,
    audience: AUDIENCE,
    scope: SCOPE
  });
}

export function logout() {
  clearIdToken();
  clearAccessToken();
  browserHistory.push('/');
}

export function requireAuth(nextState, replace) {
  if (!isLoggedIn()) {
    replace({pathname: '/'});
  }
}

export function getIdToken() {
  return localStorage.getItem(ID_TOKEN_KEY);
}

export function getAccessToken() {
  return localStorage.getItem(ACCESS_TOKEN_KEY);
}

function clearIdToken() {
  localStorage.removeItem(ID_TOKEN_KEY);
}

function clearAccessToken() {
  localStorage.removeItem(ACCESS_TOKEN_KEY);
}

// Helper function that will allow us to extract the access_token and id_token
function getParameterByName(name) {
  let match = RegExp('[#&]' + name + '=([^&]*)').exec(window.location.hash);
  return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

// Get and store access_token in local storage
export function setAccessToken() {
  let accessToken = getParameterByName('access_token');
  localStorage.setItem(ACCESS_TOKEN_KEY, accessToken);
}

// Get and store id_token in local storage
export function setIdToken() {
  let idToken = getParameterByName('id_token');
  localStorage.setItem(ID_TOKEN_KEY, idToken);
}

export function isLoggedIn() {
  const idToken = getIdToken();
  return !!idToken && !isTokenExpired(idToken);
}

function getTokenExpirationDate(encodedToken) {
  const token = decode(encodedToken);
  if (!token.exp) { return null; }

  const date = new Date(0);
  date.setUTCSeconds(token.exp);

  return date;
}

function isTokenExpired(token) {
  const expirationDate = getTokenExpirationDate(token);
  return expirationDate < new Date();
}
```

In the code above, we invoked the `auth0` library. And we have methods for storing the tokens returned from Auth0, decoding them and getting the expiry date.

> **Danger** **Note:** Replace the `CLIENT_ID` and `CLIENT_DOMAIN` with the values from your Auth0 dashboard.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cloudinary.gitbook.io/build-a-mini-netflix/build-a-mini-netflix-with-cloudinary/incorporate-authservice.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
