Skip to content

Getting Started with Authentication

This guide will walk you through implementing user authentication in your application using Root Security.

Prerequisites

  • A Root Security account with an application created
  • Your application's Client ID and Client Secret
  • Development environment with your preferred programming language

Authentication Flows

Root Security supports multiple authentication flows:

  • Username/Password: Traditional email and password authentication
  • Social Login: Authentication through Google, Facebook, GitHub, etc.
  • Single Sign-On: Enterprise authentication through SAML or OIDC
  • Passwordless: Magic links, WebAuthn, or SMS authentication

This guide focuses on implementing username/password authentication.

Implementing Username/Password Authentication

Step 1: Set Up Your Authentication UI

Create login and registration forms in your application. For a quick start, you can use our pre-built components:

import { LoginForm } from '@root-security/react';

function LoginPage() {
  return (
    <LoginForm
      clientId="YOUR_CLIENT_ID"
      domain="your-tenant.rootsecurity.com"
      onSuccess={(user, token) => {
        console.log('Logged in:', user);
        // Store the token and redirect
        localStorage.setItem('token', token);
        window.location.href = '/dashboard';
      }}
    />
  );
}
<template>
  <RootSecurityLogin
    :clientId="clientId"
    :domain="domain"
    @success="onLoginSuccess"
  />
</template>

<script>
import { RootSecurityLogin } from '@root-security/vue';

export default {
  components: { RootSecurityLogin },
  data() {
    return {
      clientId: 'YOUR_CLIENT_ID',
      domain: 'your-tenant.rootsecurity.com'
    };
  },
  methods: {
    onLoginSuccess(user, token) {
      console.log('Logged in:', user);
      localStorage.setItem('token', token);
      this.$router.push('/dashboard');
    }
  }
};
</script>

Step 2: Handle Authentication Server-Side

const express = require('express');
const { RootSecurity } = require('@root-security/auth');

const app = express();
app.use(express.json());

const rootClient = new RootSecurity({
  clientId: 'YOUR_CLIENT_ID',
  clientSecret: 'YOUR_CLIENT_SECRET',
  domain: 'your-tenant.rootsecurity.com'
});

// Verify tokens on protected routes
const authenticate = async (req, res, next) => {
  try {
    const token = req.headers.authorization?.split(' ')[1];
    if (!token) {
      return res.status(401).json({ error: 'No token provided' });
    }

    const user = await rootClient.verifyToken(token);
    req.user = user;
    next();
  } catch (error) {
    res.status(401).json({ error: 'Invalid token' });
  }
};

// Protected route example
app.get('/api/user-profile', authenticate, (req, res) => {
  res.json({ user: req.user });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});
from flask import Flask, request, jsonify
from root_security import RootSecurity, AuthError
from functools import wraps

app = Flask(__name__)

client = RootSecurity(
    client_id='YOUR_CLIENT_ID',
    client_secret='YOUR_CLIENT_SECRET',
    domain='your-tenant.rootsecurity.com'
)

def require_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth_header = request.headers.get('Authorization', '')
        if not auth_header.startswith('Bearer '):
            return jsonify({'error': 'No token provided'}), 401

        token = auth_header.split(' ')[1]
        try:
            user = client.verify_token(token)
            request.user = user
        except AuthError:
            return jsonify({'error': 'Invalid token'}), 401

        return f(*args, **kwargs)
    return decorated

@app.route('/api/user-profile')
@require_auth
def user_profile():
    return jsonify({'user': request.user})

if __name__ == '__main__':
    app.run(debug=True)

Step 3: Implement Token Management

Tokens have an expiration time. Implement a token refresh strategy:

// Example token refresh in JavaScript
async function refreshTokenIfNeeded() {
  const token = localStorage.getItem('token');
  const tokenData = parseJwt(token); // Helper to decode JWT payload

  // Check if token is nearing expiration (e.g., 5 minutes)
  const isExpiringSoon = tokenData.exp - (Date.now() / 1000) < 300;

  if (isExpiringSoon) {
    try {
      const refreshToken = localStorage.getItem('refreshToken');
      const newTokens = await rootClient.refreshToken(refreshToken);

      localStorage.setItem('token', newTokens.accessToken);
      localStorage.setItem('refreshToken', newTokens.refreshToken);
    } catch (error) {
      // Handle refresh failure - redirect to login
      window.location.href = '/login';
    }
  }
}

Next Steps

Now that you've implemented basic authentication: