MagicJS
mern.aiUniversityGitHub
  • Introduction to MagicJS
  • Why MagicJS?
  • Getting Started & Installation
  • Basic Guide
    • Create a new page using React
    • Navigate between pages
    • Create an API and integrate it with the frontend
    • Authenticate Users
      • Authorise based on Roles
    • Advanced State Management with useContent()
    • Perform CRUD Operations
    • Adding Realtime capabilities using socket
    • Handling file uploads and downloads
  • Advanced Guide
    • Understanding the concept of features in MagicJS
    • Using UI components & functions across multiple Magic Features
    • Advanced Routing of pages
    • Enable SSR
    • Access MongoDB
    • Styling pages using Tailwind CSS
  • Deploying
  • Update MagicJS
  • API References
    • Frontend
      • <LinkDisplay>
      • createSrc()
      • createUploader()
      • importUI()
      • loadConfig()
      • protected()
      • useParams()
      • useAxios()
      • useLogin()
      • useSocket()
      • useContent()
      • usePromise()
      • useNotification()
    • Backend
      • createBackendFunction()
      • data()
      • io()
      • ServerInstance()
      • utils
        • hash()
        • verifyHash()
        • initiateEmailVerification()
        • saveFileToUserUploads()
        • readFileFromUserUploads()
        • removeFileFromUserUploads()
        • assignRoleToUser()
        • unassignRoleFromUser()
        • findAllRolesByUser()
        • isUserInAnyRoles()
        • assignRoleToUser()
Powered by GitBook
On this page
  • Setting Up the UI
  • Implementing Login Functionality
  • Triggering the Function with the onClick Prop
  • Implementing Logout Functionality
  • Implementing Conditional Rendering
  • Implementing Backend Authentication
  • Triggering the Protected Backend

Was this helpful?

  1. Basic Guide

Authenticate Users

In this tutorial, we'll explore how to authenticate users and set up conditional rendering for components using MagicJS.

PreviousCreate an API and integrate it with the frontendNextAuthorise based on Roles

Last updated 1 year ago

Was this helpful?

The tool used in this guide is . You can download their free version by clicking .

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:

home.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>
    )
}
Expand for Tailwind styled code.
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>
    )
}
  • 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.

Implementing Login Functionality

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

  1. Create a backend file named "login".

  1. Write the login logic within the backend file, including the input "name: string" obtained from the frontend.

  2. Call the ctx.setCurrentUser() function to set the current user.

Refer the snippet below.

login.server.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"
})
  • 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".

home.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>
    )
}
Expand for Tailwind styled code.
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>
    )
  • 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'.

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.

home.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>
    )
}
Expand for Tailwind styled code.
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>
    )
}

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.

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.

home.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>
    )
}
Expand for Tailwind styled code.
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>
    )
}
  • 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.

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

get-my-name.server.tsx
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;
})

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:

home.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>
    )
}
Expand for Tailwind styled code.
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>
    )
}
  • 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().


The 'server.tsx' extension will be automatically appended in .

Congratulations! You've learned how to authenticate a user seamlessly in using the MagicJS framework.

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 for more information.

MERN.AI
🎉
MERN.AI
mern.ai
MERN.AI
here
Authenticate a User
Tailwind Styled Output
Tailwind Styled Output
Tailwind Styled Output
Tailwind Styled Output
Tailwind Styled Output
Output: Login