NeoSC’s local authentication provides a straightforward email/password authentication system using JWT tokens and secure password hashing.
Overview
Local authentication implements:
- SHA-256 password hashing
- Secure token generation with
secrets.token_urlsafe(32)
- Session management with MongoDB
- Automatic audit logging for all auth events
- MFA enforcement by default
Registration Flow
Register Endpoint
POST /api/auth/register
Content-Type: application/json
{
"email": "user@example.com",
"password": "secure_password",
"name": "John Doe",
"organization": "Acme Corp" // Optional, defaults to "Default Organization"
}
Response:
{
"access_token": "vTxZ9pKmQ3wLrB5nC8dF2hG6jM4sP7tY1uX0aE3bH9",
"token_type": "bearer",
"user": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "user@example.com",
"name": "John Doe",
"organization": "Acme Corp",
"role": "user",
"mfa_enabled": true
}
}
Registration Process
Email Validation
System checks if the email is already registered. Returns 400 error if email exists.
User Creation
Creates a new user with:
- Unique UUID
- Hashed password (SHA-256)
- Default role:
user
- MFA enabled by default
- Timestamp of creation
Token Generation
Generates a secure access token using secrets.token_urlsafe(32)
Audit Log
Creates an audit log entry for the registration event
Response
Returns the access token and user profile
Login Flow
Login Endpoint
POST /api/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "secure_password"
}
Response:
{
"access_token": "vTxZ9pKmQ3wLrB5nC8dF2hG6jM4sP7tY1uX0aE3bH9",
"token_type": "bearer",
"user": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "user@example.com",
"name": "John Doe",
"organization": "Acme Corp",
"role": "user",
"mfa_enabled": true
}
}
Authentication Process
Credential Validation
Verifies email exists and password hash matches stored hash
Session Creation
Generates new access token and stores in active session store
Audit Logging
Records login event with user ID, email, and timestamp
Token Response
Returns bearer token and complete user profile
Using the Access Token
Include the access token in all subsequent API requests:
GET /api/auth/me
Authorization: Bearer vTxZ9pKmQ3wLrB5nC8dF2hG6jM4sP7tY1uX0aE3bH9
Frontend Example (JavaScript):
const response = await fetch('https://api.neosc.com/api/workspaces', {
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
});
Logout
Logout Endpoint
POST /api/auth/logout
Authorization: Bearer vTxZ9pKmQ3wLrB5nC8dF2hG6jM4sP7tY1uX0aE3bH9
Response:
{
"message": "Logged out successfully"
}
Logout process:
- Extracts token from Authorization header
- Removes token from active session store
- Creates audit log entry
- Returns success message
Get Current User
Retrieve the authenticated user’s profile:
GET /api/auth/me
Authorization: Bearer vTxZ9pKmQ3wLrB5nC8dF2hG6jM4sP7tY1uX0aE3bH9
Response:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "user@example.com",
"name": "John Doe",
"organization": "Acme Corp",
"role": "user",
"mfa_enabled": true
}
Password Security
NeoSC uses SHA-256 hashing for password storage:
import hashlib
def hash_password(password: str) -> str:
return hashlib.sha256(password.encode()).hexdigest()
Passwords are never stored in plain text. Only the SHA-256 hash is persisted to the database.
Error Handling
Common Errors
Email Already Registered (400):
{
"detail": "Email already registered"
}
Invalid Credentials (401):
{
"detail": "Invalid credentials"
}
Not Authenticated (401):
{
"detail": "Not authenticated"
}
Invalid Token (401):
{
"detail": "Invalid token"
}
Frontend Integration
Complete Login Example
async function login(email, password) {
try {
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email, password })
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail);
}
const { access_token, user } = await response.json();
// Store token securely
localStorage.setItem('access_token', access_token);
localStorage.setItem('user', JSON.stringify(user));
return { token: access_token, user };
} catch (error) {
console.error('Login failed:', error);
throw error;
}
}
Security Considerations
Store access tokens securely in localStorage or sessionStorage. Never store tokens in cookies without proper security flags.
Always use HTTPS in production to protect tokens during transmission.
Implement token refresh mechanisms for long-lived sessions. Current implementation uses in-memory token store.
Enforce strong password policies on the client side before submission.
API Reference
For complete API documentation, see:
Authentication API
Full API reference for all authentication endpoints
Next Steps
Zitadel SSO
Set up enterprise SSO with Zitadel
MFA Configuration
Configure multi-factor authentication