Authentication
Studley AI uses a dual authentication system combining JWT session tokens with Supabase Auth for secure API access. All authenticated endpoints require a valid session cookie.
Authentication Methods
Studley AI supports multiple authentication methods:
Email/Password - Standard email and password authentication
Google OAuth - Sign in with Google
Clever SSO - Single sign-on for educational institutions
Multi-Factor Authentication (MFA) - Optional TOTP-based MFA for enhanced security
Session Tokens
After successful authentication, the API issues a JWT session token stored as an HTTP-only cookie.
Session tokens are signed JWTs containing:
{
userId : string // Unique user identifier
username : string // User's username or email
isAdmin ?: boolean // Admin privilege flag (optional)
iat : number // Issued at timestamp
exp : number // Expiration timestamp (7 days)
}
Token Expiration
Session tokens expire after 7 days . After expiration, users must re-authenticate.
Session tokens are HTTP-only cookies and cannot be accessed via JavaScript. This protects against XSS attacks.
Authentication Flow
1. Login
Authenticate a user and receive a session cookie:
curl -X POST https://api.studley.ai/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected] ",
"password": "SecurePassword123!"
}'
Response (Success):
{
"success" : true ,
"user" : {
"id" : "123e4567-e89b-12d3-a456-426614174000" ,
"email" : "[email protected] " ,
"name" : "student"
}
}
Response (MFA Required):
If the user has MFA enabled:
{
"success" : false ,
"mfaRequired" : true ,
"challengeId" : "challenge_abc123" ,
"factorId" : "factor_xyz789" ,
"message" : "MFA code required"
}
2. MFA Verification (If Required)
Complete MFA verification with TOTP code:
curl -X POST https://api.studley.ai/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected] ",
"password": "SecurePassword123!",
"mfaCode": "123456",
"challengeId": "challenge_abc123"
}'
Response:
{
"success" : true ,
"mfaVerified" : true ,
"user" : {
"id" : "123e4567-e89b-12d3-a456-426614174000" ,
"email" : "[email protected] " ,
"name" : "student"
}
}
3. Get Current User
Retrieve the authenticated user’s information:
curl https://api.studley.ai/api/auth/me \
-H "Cookie: session=YOUR_SESSION_TOKEN"
Response:
{
"user" : {
"id" : "123e4567-e89b-12d3-a456-426614174000" ,
"email" : "[email protected] " ,
"name" : "Jane Student" ,
"avatar_url" : "https://example.com/avatar.jpg"
}
}
4. Logout
End the user session:
curl -X POST https://api.studley.ai/api/auth/logout \
-H "Cookie: session=YOUR_SESSION_TOKEN"
Response:
{
"success" : true ,
"message" : "Logged out successfully"
}
Using Session Cookies
In Browser JavaScript
The session cookie is automatically included in requests from the browser:
const response = await fetch ( '/api/ai-tutor/chat' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json'
},
credentials: 'include' , // Important: include cookies
body: JSON . stringify ({
message: 'Explain photosynthesis' ,
sessionId: 'session_123'
})
});
const data = await response . json ();
In Server-to-Server Requests
For server-to-server API calls, manually include the session cookie:
curl -X POST https://api.studley.ai/api/generate-quiz \
-H "Content-Type: application/json" \
-H "Cookie: session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"topic": "Biology",
"numQuestions": 5
}'
Supabase Integration
Studley AI uses Supabase for authentication backend. The API handles session management through Supabase Auth:
Environment Variables
NEXT_PUBLIC_SUPABASE_URL = https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY = your-anon-key
SESSION_SECRET = your-jwt-secret-key
Never expose your SESSION_SECRET or Supabase service role key in client-side code. Use environment variables and keep them secure.
Creating Server Client
The API creates Supabase clients for server-side authentication:
import { createClient } from '@/lib/supabase/server' ;
export async function GET () {
const supabase = await createClient ();
const { data : { user }, error } = await supabase . auth . getUser ();
if ( error || ! user ) {
return NextResponse . json (
{ error: 'Not authenticated' },
{ status: 401 }
);
}
// User is authenticated
return NextResponse . json ({ user });
}
Protected Routes
Many API endpoints require authentication. Protected routes will return a 401 Unauthorized error if no valid session is present:
{
"error" : "Not authenticated"
}
Example: Protected Endpoint
curl https://api.studley.ai/api/ai-tutor/sessions \
-H "Cookie: session=YOUR_SESSION_TOKEN"
Without authentication:
{
"error" : "Not authenticated"
}
Security Best Practices
Follow these security best practices when working with the Studley AI API:
1. Use HTTPS
Always use HTTPS in production to protect session tokens in transit:
// Session cookies are marked secure in production
cookieStore . set ( 'session' , token , {
httpOnly: true ,
secure: process . env . NODE_ENV === 'production' , // HTTPS only
sameSite: 'lax' ,
maxAge: 60 * 60 * 24 * 7 , // 7 days
path: '/'
});
2. Store Secrets Securely
Never commit secrets to version control
Use environment variables for all sensitive configuration
Rotate secrets regularly
Use different secrets for development and production
3. Handle Session Expiration
Implement proper error handling for expired sessions:
try {
const response = await fetch ( '/api/auth/me' , {
credentials: 'include'
});
if ( response . status === 401 ) {
// Session expired, redirect to login
window . location . href = '/login' ;
}
const data = await response . json ();
} catch ( error ) {
console . error ( 'Authentication error:' , error );
}
4. Implement Rate Limiting
The API automatically rate limits authentication attempts to prevent brute force attacks. After multiple failed login attempts, temporary lockouts are applied.
5. Enable MFA for Sensitive Operations
Encourage users to enable multi-factor authentication for enhanced security, especially for admin accounts and sensitive operations.
OAuth Integration
Google OAuth
Authenticate using Google:
# Initiate OAuth flow
GET https://api.studley.ai/api/auth/google
The endpoint redirects to Google’s OAuth consent screen. After authorization, users are redirected back with a session token.
Clever SSO
For educational institutions using Clever:
# Initiate Clever SSO flow
GET https://api.studley.ai/api/auth/clever
# Callback endpoint
GET https://api.studley.ai/api/auth/clever/callback
Error Responses
Invalid Credentials
{
"error" : "Invalid email or password"
}
Status Code: 401 Unauthorized
Missing Required Fields
{
"error" : "Email and password are required"
}
Status Code: 400 Bad Request
Session Expired
{
"error" : "Not authenticated"
}
Status Code: 401 Unauthorized
MFA Error
{
"error" : "Invalid MFA code"
}
Status Code: 401 Unauthorized
Next Steps
AI Tutor API Start building with the AI Tutor API
Content Generation Generate study materials programmatically
Rate Limits Understanding rate limits
Error Handling Handling API errors gracefully