Documentation Index Fetch the complete documentation index at: https://docs.tryfltr.com/llms.txt
Use this file to discover all available pages before exploring further.
Session Authentication
Session authentication is designed for browser-based applications where users log in through the FLTR web interface. It uses HTTP-only cookies for secure, stateless authentication.
Overview
Session authentication provides:
15,000 requests/hour rate limit
HTTP-only cookies to prevent XSS attacks
CSRF protection built-in
Automatic session management by the browser
Same security as OAuth without the complexity
When to Use Sessions
Best for:
Single-page applications (SPAs)
Server-rendered web apps
Admin dashboards
Internal tools
Not recommended for:
Mobile apps (use OAuth)
Server-to-server integrations (use API keys)
Third-party integrations (use OAuth)
Quick Start
Enable Session Auth
Configure your application to use credentials: fetch ( 'https://api.fltr.com/v1/datasets' , {
credentials: 'include' // Send cookies with request
})
Redirect to Login
Send users to the FLTR login page: window . location . href = 'https://www.tryfltr.com/login?redirect_uri=' +
encodeURIComponent ( window . location . href );
Make API Calls
After login, session cookies are automatically included: const response = await fetch ( 'https://api.fltr.com/v1/datasets' , {
credentials: 'include'
});
Implementation
Frontend (React Example)
import { useEffect , useState } from 'react' ;
function App () {
const [ datasets , setDatasets ] = useState ([]);
const [ isAuthenticated , setIsAuthenticated ] = useState ( false );
useEffect (() => {
checkAuth ();
}, []);
// Check if user is authenticated
async function checkAuth () {
try {
const response = await fetch ( 'https://api.fltr.com/v1/auth/session' , {
credentials: 'include'
});
if ( response . ok ) {
setIsAuthenticated ( true );
loadDatasets ();
}
} catch ( error ) {
console . error ( 'Not authenticated' );
}
}
// Load datasets
async function loadDatasets () {
const response = await fetch ( 'https://api.fltr.com/v1/datasets' , {
credentials: 'include'
});
const data = await response . json ();
setDatasets ( data . datasets );
}
// Login redirect
function login () {
const redirectUri = encodeURIComponent ( window . location . href );
window . location . href = `https://www.tryfltr.com/login?redirect_uri= ${ redirectUri } ` ;
}
// Logout
async function logout () {
await fetch ( 'https://api.fltr.com/v1/auth/logout' , {
method: 'POST' ,
credentials: 'include'
});
setIsAuthenticated ( false );
setDatasets ([]);
}
if ( ! isAuthenticated ) {
return (
< div >
< h1 > Welcome to FLTR </ h1 >
< button onClick = { login } > Login </ button >
</ div >
);
}
return (
< div >
< h1 > My Datasets </ h1 >
< button onClick = { logout } > Logout </ button >
< ul >
{ datasets . map ( dataset => (
< li key = { dataset . id } > { dataset . name } </ li >
)) }
</ ul >
</ div >
);
}
export default App ;
Backend (Express.js Example)
If you need server-side session management:
import express from 'express' ;
import session from 'express-session' ;
import RedisStore from 'connect-redis' ;
import { createClient } from 'redis' ;
const app = express ();
// Redis client for session storage
const redisClient = createClient ();
await redisClient . connect ();
// Session middleware
app . use ( session ({
store: new RedisStore ({ client: redisClient }),
secret: 'your-secret-key' ,
resave: false ,
saveUninitialized: false ,
cookie: {
secure: true , // HTTPS only
httpOnly: true , // Prevent JS access
sameSite: 'lax' , // CSRF protection
maxAge: 24 * 60 * 60 * 1000 // 24 hours
}
}));
// Proxy requests to FLTR API
app . get ( '/api/datasets' , async ( req , res ) => {
if ( ! req . session . fltrAccessToken ) {
return res . status ( 401 ). json ({ error: 'Not authenticated' });
}
const response = await fetch ( 'https://api.fltr.com/v1/datasets' , {
headers: {
'Authorization' : `Bearer ${ req . session . fltrAccessToken } `
}
});
const data = await response . json ();
res . json ( data );
});
// Login callback
app . get ( '/auth/callback' , async ( req , res ) => {
const { code } = req . query ;
// Exchange code for access token (OAuth flow)
const tokenResponse = await fetch ( 'https://www.tryfltr.com/oauth/token' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/x-www-form-urlencoded' },
body: new URLSearchParams ({
grant_type: 'authorization_code' ,
code ,
client_id: process . env . FLTR_CLIENT_ID ,
client_secret: process . env . FLTR_CLIENT_SECRET ,
redirect_uri: 'http://localhost:3000/auth/callback'
})
});
const tokens = await tokenResponse . json ();
// Store in session
req . session . fltrAccessToken = tokens . access_token ;
req . session . fltrRefreshToken = tokens . refresh_token ;
res . redirect ( '/' );
});
// Logout
app . post ( '/auth/logout' , ( req , res ) => {
req . session . destroy ();
res . json ({ success: true });
});
app . listen ( 3000 );
CORS Configuration
For browser-based requests, configure CORS properly:
Development
// Allow credentials in development
fetch ( 'https://api.fltr.com/v1/datasets' , {
credentials: 'include' , // Important!
headers: {
'Content-Type' : 'application/json'
}
})
Production
Add your domain to FLTR’s allowed origins:
Go to Settings → CORS
Add your production domain: https://yourdomain.com
Save changes
FLTR will send these CORS headers:
Access-Control-Allow-Origin: https://yourdomain.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
CSRF Protection
Session authentication includes built-in CSRF protection using the double-submit cookie pattern.
How It Works
FLTR sets a CSRF token in a cookie
Your app reads the cookie and sends it in a header
FLTR validates the header matches the cookie
Implementation
// Get CSRF token from cookie
function getCsrfToken () {
const cookies = document . cookie . split ( ';' );
for ( let cookie of cookies ) {
const [ name , value ] = cookie . trim (). split ( '=' );
if ( name === 'XSRF-TOKEN' ) {
return decodeURIComponent ( value );
}
}
return null ;
}
// Include CSRF token in requests
async function makeRequest ( url , options = {}) {
const csrfToken = getCsrfToken ();
const response = await fetch ( url , {
... options ,
credentials: 'include' ,
headers: {
... options . headers ,
'X-XSRF-TOKEN' : csrfToken ,
'Content-Type' : 'application/json'
}
});
return response ;
}
// Usage
await makeRequest ( 'https://api.fltr.com/v1/datasets' , {
method: 'POST' ,
body: JSON . stringify ({ name: 'New Dataset' })
});
Axios Configuration
Axios automatically handles CSRF tokens:
import axios from 'axios' ;
const api = axios . create ({
baseURL: 'https://api.fltr.com/v1' ,
withCredentials: true , // Include cookies
xsrfCookieName: 'XSRF-TOKEN' ,
xsrfHeaderName: 'X-XSRF-TOKEN'
});
// Make requests
await api . get ( '/datasets' );
await api . post ( '/datasets' , { name: 'New Dataset' });
Session Management
Check Session Status
async function checkSession () {
try {
const response = await fetch ( 'https://api.fltr.com/v1/auth/session' , {
credentials: 'include'
});
if ( response . ok ) {
const session = await response . json ();
return {
authenticated: true ,
user: session . user ,
expiresAt: session . expires_at
};
}
} catch ( error ) {
return { authenticated: false };
}
}
Extend Session
Sessions automatically extend on each request. To manually extend:
await fetch ( 'https://api.fltr.com/v1/auth/session/refresh' , {
method: 'POST' ,
credentials: 'include'
});
Logout
async function logout () {
await fetch ( 'https://api.fltr.com/v1/auth/logout' , {
method: 'POST' ,
credentials: 'include'
});
// Redirect to home page
window . location . href = '/' ;
}
Security Best Practices
Cookie Security
FLTR sets secure cookie attributes:
Set-Cookie: fltr_session=abc123;
HttpOnly; // Prevent JavaScript access
Secure; // HTTPS only
SameSite=Lax; // CSRF protection
Max-Age=86400; // 24 hour expiry
Path=/; // Available to all paths
Frontend Security
Do:
✅ Use credentials: 'include' for all API requests
✅ Implement CSRF protection
✅ Use HTTPS in production
✅ Validate session before sensitive operations
✅ Implement logout on idle timeout
Don’t:
❌ Store session data in localStorage
❌ Access cookies from JavaScript
❌ Make API calls without CSRF tokens
❌ Trust client-side session checks alone
Backend Security
Do:
✅ Use httpOnly cookies
✅ Set SameSite=Lax or Strict
✅ Implement session expiry
✅ Validate CSRF tokens
✅ Use secure session stores (Redis)
Don’t:
❌ Store sessions in memory (doesn’t scale)
❌ Use predictable session IDs
❌ Send session cookies over HTTP
❌ Trust client-provided session data
Error Handling
401 Unauthorized
Session expired or invalid:
fetch ( 'https://api.fltr.com/v1/datasets' , {
credentials: 'include'
})
. then ( response => {
if ( response . status === 401 ) {
// Session expired - redirect to login
window . location . href = '/login' ;
}
return response . json ();
})
403 Forbidden
CSRF token invalid:
if ( response . status === 403 ) {
const error = await response . json ();
if ( error . code === 'csrf_token_invalid' ) {
// Retry request with fresh CSRF token
location . reload ();
}
}
Rate Limiting
Session authentication provides 15,000 requests/hour - the same as OAuth.
Check rate limit status:
const response = await fetch ( 'https://api.fltr.com/v1/datasets' , {
credentials: 'include'
});
const rateLimit = {
limit: response . headers . get ( 'X-RateLimit-Limit' ),
remaining: response . headers . get ( 'X-RateLimit-Remaining' ),
reset: response . headers . get ( 'X-RateLimit-Reset' )
};
console . log ( ` ${ rateLimit . remaining } / ${ rateLimit . limit } requests remaining` );
Complete Examples
Next.js App Router
// app/api/datasets/route.ts
import { cookies } from 'next/headers' ;
export async function GET () {
const cookieStore = cookies ();
const sessionCookie = cookieStore . get ( 'fltr_session' );
if ( ! sessionCookie ) {
return Response . json ({ error: 'Not authenticated' }, { status: 401 });
}
const response = await fetch ( 'https://api.fltr.com/v1/datasets' , {
headers: {
'Cookie' : `fltr_session= ${ sessionCookie . value } `
}
});
const data = await response . json ();
return Response . json ( data );
}
// app/datasets/page.tsx
'use client' ;
export default function DatasetsPage () {
const [ datasets , setDatasets ] = useState ([]);
useEffect (() => {
fetch ( '/api/datasets' )
. then ( res => res . json ())
. then ( data => setDatasets ( data . datasets ));
}, []);
return (
< div >
< h1 > Datasets </ h1 >
< ul >
{ datasets . map ( dataset => (
< li key = {dataset. id } > {dataset. name } </ li >
))}
</ ul >
</ div >
);
}
Vue.js 3
< template >
< div >
< div v-if = " ! authenticated " >
< button @ click = " login " > Login </ button >
</ div >
< div v-else >
< button @ click = " logout " > Logout </ button >
< ul >
< li v-for = " dataset in datasets " : key = " dataset . id " >
{{ dataset . name }}
</ li >
</ ul >
</ div >
</ div >
</ template >
< script setup >
import { ref , onMounted } from 'vue' ;
const authenticated = ref ( false );
const datasets = ref ([]);
async function checkAuth () {
try {
const response = await fetch ( 'https://api.fltr.com/v1/auth/session' , {
credentials: 'include'
});
if ( response . ok ) {
authenticated . value = true ;
loadDatasets ();
}
} catch ( error ) {
console . error ( 'Not authenticated' );
}
}
async function loadDatasets () {
const response = await fetch ( 'https://api.fltr.com/v1/datasets' , {
credentials: 'include'
});
const data = await response . json ();
datasets . value = data . datasets ;
}
function login () {
const redirectUri = encodeURIComponent ( window . location . href );
window . location . href = `https://www.tryfltr.com/login?redirect_uri= ${ redirectUri } ` ;
}
async function logout () {
await fetch ( 'https://api.fltr.com/v1/auth/logout' , {
method: 'POST' ,
credentials: 'include'
});
authenticated . value = false ;
datasets . value = [];
}
onMounted ( checkAuth );
</ script >
Troubleshooting
Cookies Not Being Set
Cause: CORS configuration issue
Solution:
Ensure credentials: 'include' is set
Add your domain to allowed origins in FLTR settings
Use HTTPS in production (required for secure cookies)
CSRF Token Errors
Cause: Missing or invalid CSRF token
Solution:
// Ensure X-XSRF-TOKEN header is sent
headers : {
'X-XSRF-TOKEN' : getCsrfToken ()
}
Session Expires Too Quickly
Cause: No activity extending session
Solution: Make a lightweight request periodically:
// Extend session every 10 minutes
setInterval ( async () => {
await fetch ( 'https://api.fltr.com/v1/auth/session/ping' , {
credentials: 'include'
});
}, 10 * 60 * 1000 );
Next Steps
API Keys Compare with API key authentication
OAuth When to use OAuth instead
CORS Guide Configure CORS for your domain
Security Security best practices