Client Secrets
Client secrets are secure, session-specific tokens that allow your frontend applications to interact with FaceSign's verification interface. Unlike your API key, client secrets are safe to use in client-side code and are automatically included when you create or retrieve a session.
How client secrets work
Client secrets provide a secure way to authenticate frontend requests:
- Server-side session creation - Use your API key to create a session
- Client secret returned - FaceSign returns a session-specific client secret
- Frontend integration - Pass the client secret to your frontend or mobile app
- Secure verification - Frontend uses the client secret to access the verification interface
- Automatic expiration - Client secrets expire after 1 hour for security
Client secret properties
- Name
secret
- Type
- string
- Description
The client secret token to use in frontend integrations.
- Name
createdAt
- Type
- number
- Description
Unix timestamp when the client secret was created.
- Name
expireAt
- Type
- number
- Description
Unix timestamp when the client secret expires (1 hour from creation).
- Name
url
- Type
- string
- Description
Pre-built URL for hosted verification flow including the client secret.
Using client secrets
Web integration
For web applications, you can either redirect users to the hosted flow or use the JavaScript SDK:
Web integration
<!-- Server-side: Get client secret -->
<script>
// Pass client secret from your server
const clientSecret = "{{ clientSecret }}"; // From your backend
const verificationUrl = `https://verify.facesign.ai/?client_secret=${clientSecret}`;
// Redirect user to verification
window.location.href = verificationUrl;
</script>
Mobile integration
For mobile applications, use the native SDKs:
Mobile integration
import FaceSignSDK
class VerificationViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
startVerification()
}
func startVerification() {
// Get client secret from your backend
getClientSecret { [weak self] clientSecret in
DispatchQueue.main.async {
let config = FaceSignConfig(
clientSecret: clientSecret,
delegate: self
)
let verificationVC = FaceSignViewController(config: config)
self?.present(verificationVC, animated: true)
}
}
}
func getClientSecret(completion: @escaping (String) -> Void) {
// Call your backend API to get client secret
APIClient.createSession { result in
switch result {
case .success(let response):
completion(response.clientSecret)
case .failure(let error):
print("Failed to get client secret: \(error)")
}
}
}
}
extension VerificationViewController: FaceSignDelegate {
func verificationCompleted(session: FaceSignSession) {
if session.report.isVerified {
// Verification successful
navigateToDashboard()
} else {
// Verification failed
showErrorAlert("Verification failed")
}
}
func verificationCancelled() {
// User cancelled verification
dismiss(animated: true)
}
}
Security considerations
Client secrets are safe for frontend use
Unlike API keys, client secrets are designed to be safe for client-side use:
- Session-specific - Each client secret is tied to a single session
- Time-limited - Automatically expire after 1 hour
- Read-only - Cannot be used to create new sessions or access other data
- Domain-restricted - Can be restricted to specific domains (contact support)
Best practices
- Fetch on demand - Get client secrets from your backend when needed
- Handle expiration - Refresh client secrets if they expire during verification
- Secure transmission - Always use HTTPS when transmitting client secrets
- Don't store long-term - Client secrets are meant for immediate use
Secure implementation
// Secure endpoint to create sessions
app.post('/api/create-verification', authenticate, async (req, res) => {
// Verify user is authenticated
if (!req.user) {
return res.status(401).json({ error: 'Unauthorized' });
}
try {
const { session, clientSecret } = await facesignClient.sessions.create({
clientReferenceId: req.user.id,
metadata: {
userId: req.user.id,
email: req.user.email,
ipAddress: req.ip
},
modules: [{ type: 'identityVerification' }]
});
// Store session in your database
await db.verifications.create({
sessionId: session.id,
userId: req.user.id,
status: session.status,
createdAt: new Date()
});
// Return only the client secret to frontend
res.json({
clientSecret: clientSecret.secret,
sessionId: session.id
});
} catch (error) {
console.error('Session creation failed:', error);
res.status(500).json({ error: 'Failed to create verification session' });
}
});
Handling expiration
Client secrets expire after 1 hour. If verification takes longer or you need to restart the process:
Handle expiration
async function handleClientSecretExpiration(sessionId: string) {
try {
// Call your backend to refresh the client secret
const response = await fetch(`/api/refresh-verification/${sessionId}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${userToken}`,
}
});
const { clientSecret } = await response.json();
// Reinitialize FaceSign with new client secret
const facesign = new FaceSign({
clientSecret: clientSecret
});
await facesign.mount('#verification-container');
} catch (error) {
console.error('Failed to refresh client secret:', error);
// Redirect to start a new verification session
window.location.href = '/start-verification';
}
}
// Backend endpoint for refreshing
app.post('/api/refresh-verification/:sessionId', authenticate, async (req, res) => {
const { sessionId } = req.params;
// Verify the session belongs to the authenticated user
const verification = await db.verifications.findFirst({
where: { sessionId, userId: req.user.id }
});
if (!verification) {
return res.status(404).json({ error: 'Session not found' });
}
try {
const { clientSecret } = await facesignClient.sessions.refreshSecret(sessionId);
res.json({
clientSecret: clientSecret.secret
});
} catch (error) {
console.error('Failed to refresh client secret:', error);
res.status(500).json({ error: 'Failed to refresh client secret' });
}
});