Authentication and Authorization

ProductFlo uses a comprehensive authentication and authorization system to secure your data while providing a seamless user experience. This guide explains the authentication methods, token handling, and authorization patterns used in the API.

Authentication Methods

ProductFlo supports multiple authentication methods to meet diverse security requirements:

Standard email and password authentication with optional two-factor authentication

JWT Authentication

All API requests (except for the authentication endpoints themselves) require a JSON Web Token (JWT) for authentication. This token is provided in the Authorization header using the Bearer scheme:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Token Structure

The JWT contains the following important claims:

  • sub: The user’s unique identifier
  • exp: Expiration time
  • iat: Issued at time
  • tenant_id: The current tenant context (optional)
  • role: The user’s role
  • permissions: The user’s permissions (optional)

Token Lifecycle

1

Login

User authenticates using their preferred method (email/password, OAuth, etc.)

2

Token Issuance

Server generates an access token and refresh token

3

API Access

User includes the access token in API requests

4

Token Expiration

Access token expires after a set time (1 hour by default)

5

Token Refresh

User uses the refresh token to obtain a new access token

Authentication Flow

Email/Password Authentication

async function login(email, password) {
  const response = await fetch('https://api.productflo.io/auth/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password }),
    credentials: 'include' // Important for cookie handling
  });
  
  if (!response.ok) {
    throw new Error('Authentication failed');
  }
  
  const data = await response.json();
  // Store the token securely
  localStorage.setItem('accessToken', data.session.access_token);
  return data;
}

OAuth Authentication

// 1. Initiate OAuth flow
async function initiateOAuth(provider) {
  const response = await fetch('https://api.productflo.io/auth/provider', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ provider }) // e.g., 'google', 'github'
  });
  
  const data = await response.json();
  // Redirect user to OAuth provider
  window.location.href = data.url;
}

// 2. Handle the OAuth callback
// This happens automatically when the user is redirected back to your app
// The server exchanges the code for tokens and sets the cookies/session

Token Refresh

Access tokens have a limited lifetime (typically 1 hour) for security. When an access token expires, you should use the refresh token to obtain a new one:

async function refreshToken() {
  const refreshToken = localStorage.getItem('refreshToken');
  
  const response = await fetch('https://api.productflo.io/auth/refresh-session', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${refreshToken}`
    }
  });
  
  if (!response.ok) {
    // Refresh failed, user needs to log in again
    redirectToLogin();
    return;
  }
  
  const data = await response.json();
  localStorage.setItem('accessToken', data.session.access_token);
  return data;
}

ProductFlo also supports cookie-based authentication to simplify token management and improve security. When enabled, the server sets HTTP-only cookies containing the JWT, which are automatically included in subsequent requests:

When using cookie-based authentication, you must include credentials: 'include' in your fetch requests to ensure cookies are sent.

Two-Factor Authentication (2FA)

ProductFlo supports two-factor authentication for additional security:

1

Enable 2FA

User enables 2FA in their account settings

2

Initial Login

User logs in with username and password

3

2FA Challenge

Server responds with a 2FA challenge

4

Submit 2FA Code

User submits the 2FA code from their authenticator app

5

Complete Authentication

Server verifies the code and completes authentication

Role-Based Authorization

ProductFlo uses role-based access control (RBAC) to determine what actions users can perform. Common roles include:

  • Administrator: Full access to all resources
  • Owner: Full access to owned resources
  • Member: Limited access based on assigned permissions
  • Viewer: Read-only access to specific resources
  • Guest: Very limited access to shared resources

Roles are specified in the JWT and checked on each API request.

Permission Structure

Permissions in ProductFlo are structured as follows:

{
  "permissions": {
    "products": {
      "create": true,
      "read": true,
      "update": true,
      "delete": false
    },
    "teams": {
      "create": false,
      "read": true,
      "update": false,
      "delete": false
    },
    "files": {
      "create": true,
      "read": true,
      "update": true,
      "delete": false,
      "share": false
    }
  }
}

Session Management

ProductFlo maintains user sessions to track active users and their authentication state:

GET /auth/session

Get current session information

POST /auth/logout

End the current session

Session Properties

{
  "session_id": "sess_123456789",
  "user_id": "user_987654321",
  "created_at": "2023-05-01T12:34:56.789Z",
  "expires_at": "2023-05-02T12:34:56.789Z",
  "last_active_at": "2023-05-01T15:30:45.123Z",
  "ip_address": "192.168.1.1",
  "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...",
  "current_tenant_id": "tenant_123"
}

Best Practices

When implementing authentication in your application, follow these best practices:

  1. Secure Token Storage: Store tokens in secure HTTP-only cookies or securely in localStorage.

  2. Implement Refresh Logic: Automatically refresh tokens when they expire.

  3. Logout Properly: Clear all tokens and cookies when the user logs out.

  4. Handle Errors Gracefully: Redirect to the login page when authentication fails.

  5. Use HTTPS: Always use HTTPS to prevent token interception.

  6. Implement CSRF Protection: Use anti-CSRF tokens for cookie-based authentication.

  7. Verify Permissions: Check permissions before performing actions to provide appropriate UI feedback.

  8. Consider Session Timeouts: Implement idle timeouts for sensitive applications.

Security Considerations

ProductFlo implements several security measures to protect authentication:

  • Rate Limiting: Prevents brute force attacks
  • JWT Signing: Ensures tokens cannot be tampered with
  • Short Token Lifetime: Limits the window of opportunity for token misuse
  • HTTP-Only Cookies: Prevents JavaScript access to tokens
  • Secure Cookie Flag: Ensures cookies are only sent over HTTPS
  • IP Binding: Optional binding of tokens to specific IP addresses
  • Audit Logging: Records all authentication events for security monitoring