# Authenticate Users

{% hint style="success" %}
The tool used in this guide is [MERN.AI](https://mern.ai/). You can download their free version by clicking [here](https://mern.ai/download).
{% endhint %}

{% embed url="<https://www.youtube.com/watch?v=RVoUtwoCHnI>" %}
Authenticate a User
{% endembed %}

## Setting Up the UI

1. Create a file named "home" in the 'main-features' directory with the path as "/".
2. Add a button with label "Login" and display the details of the current user using useLogin hook.

> Refer the below snippet:

{% code title="home.tsx" %}

```tsx
import React from "react"
import { Button } from "antd"
import { useLogin } from "@magicjs.dev/frontend"

export default function Component(props: any) {
    const { current } = useLogin()
    return (
        <div>
            <h1>{`Current User: ${current?.currentUser?.name}`}</h1>
            <Button>Login</Button>
        </div>
    )
}
```

{% endcode %}

<details>

<summary>Expand for Tailwind styled code.</summary>

```tsx
import React from "react"
import { Button } from "antd"
import { useLogin } from "@magicjs.dev/frontend"

export default function Component(props: any) {
    const { current } = useLogin()
    return (
        <div className="flex flex-col items-center justify-center h-screen">

            <h1 className="font-semi-bold text-4xl tracking-wide pb-8">
                {`Current User: ${current?.currentUser?.name}`}
            </h1>

            <Button className="text-xl w-40 h-14">Login</Button>
        </div>
    )
}
```

</details>

* The `useLogin` hook is imported from the '`@magicjs.dev/frontend`' and is used to get the `current` object, which contains the information about the current user's details.
* An `<h1>` element is used to display the name of the current user.
* The `?.` operator is used for optional chaining, ensuring that the code does not throw an error if `current` or `currentUser` is undefined or null.

<figure><img src="/files/un5l2MhGOMBj0KKUAlOy" alt=""><figcaption><p>Tailwind Styled Output</p></figcaption></figure>

## Implementing Login Functionality

Let's develop the login functionality by creating a backend file named "login".

1. Create a backend file named "login".&#x20;

{% hint style="success" %}
The 'server.tsx' extension will be automatically appended in [MERN.AI](https://mern.ai/).
{% endhint %}

2. Write the login logic within the backend file, including the input "name: string" obtained from the frontend.
3. Call the `ctx.setCurrentUser()` function to set the current user.

> Refer the snippet below.

{% code title="login.server.tsx" %}

```tsx
import { createBackendFunction, useFunctionContext } from "@magicjs.dev/backend"

export default createBackendFunction(async function (name: string) {
    const ctx = useFunctionContext(this)

    ctx.setCurrentUser({ _id: "test-user", name })

    return "Message from server"
})
```

{% endcode %}

* The function takes a single parameter `name`, which is expected to be a string. This parameter represents the name of the user being set as the current user.
* Inside the function body, the `useFunctionContext` function is called with `this` as its argument.
* The `ctx.setCurrentUser` method is called with an object containing `_id` and `name` properties. This method is provided by the `@magicjs.dev/backend` library for setting the current user within the backend function's context.
* The function returns the string "Message from server". This is the response that will be sent back to the client when the backend function is invoked.

### Triggering the Function with the onClick Prop

Refer the below code to call this function in the frontend file "`home.tsx`".

{% code title="home.tsx" %}

```tsx
import React from "react"
import { Button } from "antd"
import { useLogin } from "@magicjs.dev/frontend"
import loginServer from "./login.server"

export default function Component(props: any) {
    const { current } = useLogin()
    return (
        <div>
            <h1>{`Current User: ${current?.currentUser?.name}`}</h1>
            
            <Button onClick={() => loginServer('John')}>
                Login
            </Button>
        </div>
    )
}
```

{% endcode %}

<details>

<summary>Expand for Tailwind styled code.</summary>

```tsx
import React from "react"
import { Button } from "antd"
import { useLogin } from "@magicjs.dev/frontend"
import loginServer from "./login.server"

export default function Component(props: any) {
    const { current } = useLogin()
    return (
        <div className="flex flex-col items-center justify-center h-screen">
            <h1 className="font-semi-bold text-4xl tracking-wide pb-8">
                {`Current User: ${current?.currentUser?.name}`}
            </h1>

            <Button onClick={() => loginServer("John")} className="text-xl w-40 h-14">
                Login
            </Button>
        </div>
    )
```

</details>

* `loginServer` is imported from "./login.server", it is the backend function responsible for handling the login process.
* When the button is clicked, it triggers an arrow function that calls the `loginServer` function with the name 'John'.

<figure><img src="/files/ew7Hm82USK1JXDQ2W42u" alt="Output: Login"><figcaption><p>Tailwind Styled Output</p></figcaption></figure>

## Implementing Logout Functionality

1. Update the UI file "`home.tsx`" by adding a logout button.
2. Add the logout function near to `current`, and invoke it directly in the onClick prob.

> Refer the snippet below.

{% code title="home.tsx" %}

```tsx
import React from "react"
import { Button } from "antd"
import { useLogin } from "@magicjs.dev/frontend"
import loginServer from "./login.server"

export default function Component(props: any) {
    const { current, logout } = useLogin()
    return (
        <div>
            <h1>{`Current User: ${current?.currentUser?.name}`}</h1>

            <Button onClick={() => loginServer('John')}>
                Login
            </Button>

            <Button onClick={() => logout()}>
                Logout
            </Button>
        </div>
    )
}
```

{% endcode %}

<details>

<summary>Expand for Tailwind styled code.</summary>

```tsx
import React from "react"
import { Button } from "antd"
import { useLogin } from "@magicjs.dev/frontend"
import loginServer from "./login.server"

export default function Component(props: any) {
    const { current, logout } = useLogin()
    return (
        <div className="flex flex-col items-center justify-center h-screen">
            <h1 className="font-semi-bold text-4xl tracking-wide pb-8">
                {`Current User: ${current?.currentUser?.name}`}
            </h1>
            <div>
                <Button onClick={() => loginServer("John")} className="text-xl w-40 h-14">
                    Login
                </Button>
                <Button onClick={() => logout()} className="text-xl w-40 h-14">
                    Logout
                </Button>
            </div>
        </div>
    )
}

```

</details>

<figure><img src="/files/s7HrrbGDSB9NNjxd7mQs" alt=""><figcaption><p>Tailwind Styled Output</p></figcaption></figure>

{% hint style="success" %}
The logout functionality is seamlessly integrated into the application without the need for a separate backend function. This capability is provided by the `useLogin` hook imported from '`@magicjs.dev/frontend`', simplifying the implementation of authentication features.
{% endhint %}

## Implementing Conditional Rendering

Let's make the Logout button invisible when a user is not logged in, by wrapping it within a conditional statement.

> Refer the snippet below.

{% code title="home.tsx" %}

```tsx
import React from "react"
import { Button } from "antd"
import { useLogin } from "@magicjs.dev/frontend"
import loginServer from "./login.server"

export default function Component(props: any) {
    const { current, logout } = useLogin()
    return (
        <div>

            <h1>{`Current User: ${current?.currentUser?.name}`}</h1>

            <Button onClick={() => loginServer('John')}>
                Login
            </Button>

            {
                current.isAuthenticated === true ? (
                    <Button onClick={() => logout()}>
                        Logout
                    </Button>
                ) : null
            }
        </div>
    )
}
```

{% endcode %}

<details>

<summary>Expand for Tailwind styled code.</summary>

```tsx
import React from "react"
import { Button } from "antd"
import { useLogin } from "@magicjs.dev/frontend"
import loginServer from "./login.server"

export default function Component(props: any) {
    const { current, logout } = useLogin()
    return (
        <div className="flex flex-col items-center justify-center h-screen">
            <h1 className="font-semi-bold text-4xl tracking-wide pb-8">
                {`Current User: ${current?.currentUser?.name}`}
            </h1>

            <div>
                <Button onClick={() => loginServer("John")} className="text-xl w-40 h-14">
                    Login
                </Button>

                {
                    current.isAuthenticated === true ? (
                        <Button onClick={() => logout()} className="text-xl w-40 h-14">
                            Logout
                        </Button>
                    ) : null
                }
            </div>
        </div>
    )
}

```

</details>

* The "Logout" button is conditionally rendered using (`current.isAuthenticated === true ? ... : null`). This ensures that the "Logout" button is only displayed when the user is authenticated or logged in.

<figure><img src="/files/g3fTfjf8IW9XSYNb2ZFl" alt=""><figcaption><p>Tailwind Styled Output</p></figcaption></figure>

## Implementing Backend Authentication

In addition to the frontend authentication, we'll also explore backend authentication to further enhance the security of the application. This includes securing backend APIs and endpoints to ensure that only authenticated users can access protected resources.

1. Create a backend file named "`get-my-name`" in the `main-features` directory.
2. Create a conditional statement to check if the user is authenticated. If authenticated, return the current user's name; otherwise, return "User not signed in".

> Refer the snippet below

{% code title="get-my-name.server.tsx" %}

```typescript
import { createBackendFunction, useFunctionContext } from "@magicjs.dev/backend"

export default createBackendFunction(async function () {
    const ctx = useFunctionContext(this)

    if (ctx.isAuthenticated === false) {
        return "User not signed in"
    }

    return ctx.currentUser.name;
})
```

{% endcode %}

### Triggering the Protected Backend

In the '`home.tsx`' file, import `getMyNameServer` in the frontend and call the function using the button.

> Refer the code below:

{% code title="home.tsx" %}

```tsx
import React from "react"
import { Button } from "antd"
import { useLogin } from "@magicjs.dev/frontend"
import loginServer from "./login.server"
import getMyNameServer from "./get-my-name.server"

export default function Component(props: any) {
    const { current, logout } = useLogin()
    return (
        <div>

            <h1>{`Current User: ${current?.currentUser?.name}`}</h1>

            <Button onClick={() => loginServer('John')}>
                Login
            </Button>

            <Button onClick={() => getMyNameServer().then((name) => alert(name))}>
                Call Protected Backend
            </Button>

            {
                current.isAuthenticated === true ? (
                    <Button onClick={() => logout()}>
                        Logout
                    </Button>
                ) : null
            }
        </div>
    )
}
```

{% endcode %}

<details>

<summary>Expand for Tailwind styled code.</summary>

```tsx
import React from "react"
import { Button } from "antd"
import { useLogin } from "@magicjs.dev/frontend"
import loginServer from "./login.server"
import getMyNameServer from "./get-my-name.server"

export default function Component(props: any) {
    const { current, logout } = useLogin()
    return (
        <div className="flex flex-col items-center justify-center h-screen">
            <h1 className="font-semi-bold text-4xl tracking-wide pb-8">
                {`Current User: ${current?.currentUser?.name}`}
            </h1>

            <div>
                <Button onClick={() => loginServer("John")} className="text-xl w-40 h-14">
                    Login
                </Button>

                <Button onClick={() => getMyNameServer().then((name) => alert(name))} className="text-xl w-120 h-14">
                    Call Protected Backend
                </Button>

                {
                    current.isAuthenticated === true ? (
                        <Button onClick={() => logout()} className="text-xl w-40 h-14">
                            Logout
                        </Button>
                    ) : null
                }
            </div>
        </div>
    )
}

```

</details>

* The above update in the code renders a `<Button>` component labelled "Call Protected Backend".
* When this button is clicked, it triggers an asynchronous operation to call a function named `getMyNameServer()`.
* Upon successfully resolving the promise returned by `getMyNameServer()`, the function `alert()` is invoked to display the response from `getMyNameServer()`.

<figure><img src="/files/Wzj4GJ3fjN65tHkxXHMy" alt=""><figcaption><p>Tailwind Styled Output</p></figcaption></figure>

:tada: Congratulations! You've learned how to authenticate a user seamlessly in [MERN.AI](https://mern.ai/) using the MagicJS framework.

{% hint style="success" %}
A pre-developed magic feature for authentication is available in mern.ai. You can simply import the feature and integrate it to your project. Visit [mern.ai](#mern.ai) for more information.
{% endhint %}

***


---

# 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://skyslit.gitbook.io/magicjs/basic-guide/authenticate-users.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.
