Authenticate Users
In this tutorial, we'll explore how to authenticate users and set up conditional rendering for components using MagicJS.
Setting Up the UI
Create a file named "home" in the 'main-features' directory with the path as "/".
Add a button with label "Login" and display the details of the current user using useLogin hook.
Refer the below snippet:
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>
)
}
The
useLogin
hook is imported from the '@magicjs.dev/frontend
' and is used to get thecurrent
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 ifcurrent
orcurrentUser
is undefined or null.

Implementing Login Functionality
Let's develop the login functionality by creating a backend file named "login".
Create a backend file named "login".
The 'server.tsx' extension will be automatically appended in MERN.AI.
Write the login logic within the backend file, including the input "name: string" obtained from the frontend.
Call the
ctx.setCurrentUser()
function to set the current user.
Refer the snippet below.
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 withthis
as its argument.The
ctx.setCurrentUser
method is called with an object containing_id
andname
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
".
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>
)
}
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
Update the UI file "
home.tsx
" by adding a logout button.Add the logout function near to
current
, and invoke it directly in the onClick prob.
Refer the snippet below.
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>
)
}

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.
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>
)
}
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.
Create a backend file named "
get-my-name
" in themain-features
directory.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
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:
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>
)
}
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 functionalert()
is invoked to display the response fromgetMyNameServer()
.

🎉 Congratulations! You've learned how to authenticate a user seamlessly in MERN.AI 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 mern.ai for more information.
Last updated