Home>Developer Toolkit>Handling authentication & authorization:

Handling authentication & authorization:

catalyst usecase author
Srilakshmi | Technical writer

Inside the Cookbook

  • Introduction
    • Understanding authentication and authorization: The foundation of app security
      • Session-based authentication
      • Token-based authentication
      • Auth with third-party providers
      • Necessity of Role-based access control (RBAC)
    • Why are these important?
      • Simplifying authentication and authorization with Catalyst
        • Hosted Authentication
        • Managing users and roles with Catalyst
      • Build with Catalyst
        • Conclusion

          Introduction

          In this guide, you’ll learn how to:

          • Effortlessly verify your users’ identities with smart authentication options.

          • Control access and permissions using simple yet powerful authorization tools.

          • Choose between Hosted and Embedded Authentication to fit your app’s unique needs.

           

          Before diving in, let’s clarify a few key terms essential for app security:

          • Authentication: Verifying who a user, system, or entity really is before granting access.

          • Authorization: Determining what an authenticated user is allowed to do or access within your application.

          • Secure Token Management: Ensuring that once a user is authenticated, their session and credentials are handled safely, preventing unauthorized use or token theft.

          You’ve built an awesome app, but do you really know who’s using it? Think of authentication as checking ID at the door it answers: “Who’s trying to get in?” Whether logging in with a username and password or signing in with Google, authentication makes sure users are who they claim to be.

          Once inside, authorization decides what rooms they can enter. It answers: “What can this user do?” Maybe they can read messages but not delete them, or edit content but not manage users. Authorization sets these boundaries, keeping your app safe and organized.

          If you want your app to be secure, user-friendly, and scalable without complicated code, this guide is for you. Let’s get started!

          Understanding authentication and authorization: The foundation of app security

          Let’s take a look at the common approaches in practice

          Session-based authentication

          This Stores login sessions on the server. After a user logs in, a session ID is generated and stored in a cookie on the client's side. This is common in traditional web applications (especially those using server-side rendering). The server validates the session on each request.

          Token-based authentication

          This often uses JWTs (JSON Web Tokens). After login, the server issues a signed token, which the client stores (usually in memory or local storage) and sends in the authorization header with each request. It's useful for stateless APIs and mobile apps and requires careful handling of token storage and expiration and refresh mechanisms.

           

          Auth with third-party providers

          Allows users to authenticate via services like Google, GitHub, or Facebook. Simplifies the login process for users, but requires more configuration (redirects, scopes, token exchange, etc.) and often uses OpenID Connect (OIDC) on top of OAuth for identity information.

          Necessity of Role-based access control (RBAC)

          This assigns users to roles such as “admin,” “editor,” or “viewer,” and grants permissions based on those roles. It can be combined with any of the above authentication methods to enforce access control in the application.

          Why are these important?

          Without authentication, anyone could use your app anonymously, leading to chaos and potential security breaches.

          Without authorization, authenticated users might do things they shouldn’t like deleting data they shouldn’t access.

          Together, authentication and authorization keep your app smart and secure

          Simplifying authentication and authorization with Catalyst

          • Implementing these systems securely from scratch is tough and time-consuming.
          • Explore Catalyst by Zoho, a full stack cloud platform designed to handle these heavy lifting tasks for you.
          • How Catalyst makes authentication easy:
            Catalyst offers two main approaches for adding login capabilities:
          • Hosted Authentication
          • Embedded Authentication  
             

          Managing users and roles with Catalyst

          After users log in, what controls their access? Catalyst’s user roles system:

          • Define roles—groups of permissions, like Admin, Editor, Viewer, or custom roles you create.

          • Assign roles to users manually or automatically during signup.

          • Enforce authorization in your app by checking user roles via Catalyst SDKs.

          • Manage all of this easily in the Catalyst Console—no backend coding needed.

          For example, your app can restrict bug deletion only to users with the Admin role, while others can only submit or view bugs.

          Build with Catalyst

          Build with Catalyst: QuickFix bug reporter app 

          Try the app live here: [QuickFix]

          Imagine building QuickFix—a simple bug reporter designed for small teams.

          • Users authenticate securely via Catalyst’s hosted login page.

          • Once logged in, the user’s role determines what they can see and do.

          Step 1: Create a new project in Catalyst Console 

          Step 2: Initialize the project locally 

          Open your terminal and run:

          
          npm install -g zcatalyst-cli# (if you haven’t installed Catalyst CLI yet)
          catalyst init
            

           

          • Pick the QuickFix project you made.

          • Choose Basic I/O Function for the backend.

          • Choose Basic Web App for the frontend.

          Step 3: Check out the sample frontend code  

          Replace your index.html code inside Client folder with the below sample code

           

          
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8" />
              <meta name="viewport" content="width=device-width, initial-scale=1" />
              <title>QuickFix - Bug Reporter</title>
              <link rel="stylesheet" href="main.css" />
              <script src="https://sdk.catalyst.zoho.com/auth.js" ></script>
          </head>
          <body>
              <header>
                  <button id="LoginBtn">Login</button>
                  <button id="LogoutBtn" style="display:none;">Logout</button>
              </header>
              <main>
                  <div class="center-content">
                      <h1>⚡ QuickFix</h1>
                      <p class="subtitle">Simple Bug Reporter for Small Teams</p>
                      <p class="description">Track bugs easily, collaborate smoothly, and ship faster.</p>
                  </div>
                  <section id="app" style="display:none;">
                      <p id="welcomeMsg" class="welcome"></p>
                      <form id="bugForm" class="bug-form">
                          <input type="text" id="bugTitle" placeholder="Bug title..." required />
                          <textarea id="bugDesc" placeholder="Describe the bug..." required></textarea>
                          <button type="submit">Submit Bug</button>
                      </form>
                      <h3>Your Bugs</h3>
                      <ul id="bugList"></ul>
                      <div id="admin-section" style="display:none;">
                          <h3>Admin Panel - All Bugs</h3>
                          <ul id="allBugList"></ul>
                      </div>
                  </section>
              </main>
              <script src="main.js"></script>
          </body>
          </html>
          

           

          
          /*css stylesheet */
          * {
              box-sizing: border-box;
              margin: 0;
              padding: 0;
              font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
              color: #333;
          }
          body {
              background: #f9faff;
              min-height: 100vh;
              display: flex;
              flex-direction: column;
              align-items: center;
          }
          /* Header with Login/Logout top right */
          header {
              width: 100%;
              padding: 15px 30px;
              display: flex;
              justify-content: flex-end;
              background: #fff;
              box-shadow: 0 2px 5px rgba(0,0,0,0.1);
              position: fixed;
              top: 0;
              left: 0;
              z-index: 100;
          }
          header button {
              background: #007bff;
              color: #fff;
              border: none;
              padding: 8px 16px;
              border-radius: 5px;
              cursor: pointer;
              font-weight: 600;
              transition: background-color 0.3s ease;
          }
          header button:hover {
              background: #0056a3;
          }
          /* Main content */
          main {
              margin-top: 80px; /* space for fixed header */
              max-width: 600px;
              width: 100%;
              padding: 20px 30px;
              background: white;
              border-radius: 8px;
              box-shadow: 0 8px 20px rgba(0,0,0,0.1);
          }
          /* Centered title & subtitle */
          .center-content {
              text-align: center;
              margin-bottom: 30px;
          }
          h1 {
              font-size: 3rem;
              margin-bottom: 10px;
              color: #007bff;
          }
          .subtitle {
              font-size: 1.3rem;
              font-weight: 500;
              color: #555;
              margin-bottom: 8px;
          }
          .description {
              font-size: 1rem;
              color: #777;
          }
          /* Welcome message */
          .welcome {
              font-weight: 600;
              font-size: 1.2rem;
              margin-bottom: 20px;
          }
          /* Bug form */
          .bug-form {
              display: flex;
              flex-direction: column;
              margin-bottom: 25px;
          }
          .bug-form input,
          .bug-form textarea {
              padding: 12px;
              margin-bottom: 15px;
              border: 1px solid #ccc;
              border-radius: 6px;
              font-size: 1rem;
              resize: vertical;
              font-family: inherit;
          }
          .bug-form button {
              width: 150px;
              align-self: flex-start;
              background: #28a745;
              color: white;
              border: none;
              padding: 10px 0;
              border-radius: 6px;
              font-weight: 600;
              cursor: pointer;
              transition: background-color 0.3s ease;
          }
          .bug-form button:hover {
              background: #1e7e34;
          }
          /* Lists */
          h3 {
              color: #007bff;
              margin-bottom: 12px;
          }
          ul {
              list-style: none;
              padding-left: 0;
          }
          li {
              background: #e9ecef;
              margin-bottom: 10px;
              padding: 12px 15px;
              border-radius: 6px;
              font-size: 1rem;
              color: #444;
          }
          /* Admin section styling */
          #admin-section {
              margin-top: 40px;
              border-top: 1px solid #ddd;
              padding-top: 20px;
          }
           

           

          
          //script
          const loginBtn = document.getElementById("LoginBtn");
          const logoutBtn = document.getElementById("LogoutBtn");
          const welcomeMsg = document.getElementById("welcomeMsg");
          const app = document.getElementById("app");
          const bugForm = document.getElementById("bugForm");
          const bugList = document.getElementById("bugList");
          const allBugList = document.getElementById("allBugList");
          const adminSection = document.getElementById("admin-section");
          //Catalyst native authentication hosten live url
          loginBtn.onclick = () => {
              window.location.href = "https://quickfixbugreporter-875627827.development.catalystserverless.com/__catalyst/auth/login";
          };
          logoutBtn.onclick = () => {
              catalyst.auth.signOut();
              location.reload();
          };
          window.onload = async () => {
              try {
                  const user = await catalyst.auth.getCurrentUser();
                  loginBtn.style.display = "none";
                  logoutBtn.style.display = "inline";
                  app.style.display = "block";
                  welcomeMsg.innerText = `Welcome, ${user.first_name} (${user.role})!`;
                  loadUserBugs(user);
                  if (user.role === "Admin") {
                      adminSection.style.display = "block";
                      loadAllBugs();
                  }
              } catch (err) {
                  console.log("Not logged in.");
              }
          };
          // Sample functions for local testing – replace with Catalyst functions
          function loadUserBugs(user) {
              // Simulate loading user-specific bugs
              bugList.innerHTML = `
                  Login Error
          Login fails on mobile - Status: Open
              `;
          }
          function loadAllBugs() {
              // Simulate loading all bugs
              allBugList.innerHTML = `
                  Dashboard Crash
          Crashes when filters are applied - Status: In Progress
              `;
          }
          bugForm.onsubmit = (e) => {
              e.preventDefault();
              const title = document.getElementById("bugTitle").value.trim();
              const desc = document.getElementById("bugDesc").value.trim();
              if (title && desc) {
                  const newBug = document.createElement("li");
                  newBug.innerHTML = `${title}
          ${desc} - Status: Open`;
                  bugList.appendChild(newBug);
                  bugForm.reset();
                  alert("Bug submitted (simulated). Connect to backend to save.");
              }
          };
            

           

          Step 5: Build your backend 

          Write your backend logic inside the functions/ folder to handle bugs and user roles securely.

          
          def handler(context, event):
              user = context.auth.get_current_user()
              if not user:
                  return {
                      "status": "error",
                      "message": "User not authenticated"
                  }
              if user['role'] == 'Admin':
                  return {
                      "message": "Welcome Admin"
                  }
              else:
                  return {
                      "message": "Hello User"
                  }
           

           

           

          We've attached a few images showcasing the perks of Catalyst's authentication system. You don't need to worry about any of the code; it's fully managed. From signup and strong password enforcement to email confirmation and security restrictions, Catalyst takes care of it all for you.


           


           

          Conclusion

          • Authentication and authorization are the backbone of secure apps. Catalyst by Zoho takes away the pain of building these systems, so you can build smarter, safer, and more robust apps faster.

          • Whether you want a quick hosted login or a fully embedded experience, Catalyst has you covered. And with built-in role management, your app stays secure and user-friendly.