Authentification et configuration
Écrit par Stanislas
Dernière mise à jour Il y a 7 mois
Authentifiez vos utilisateurs avec l'API Swiftask Public Bot à l'aide d'un simple point d'extrémité REST, puis configurez votre client GraphQL pour les appels d'API ultérieurs.
Présentation
Le processus d'authentification Swiftask se déroule en deux étapes : tout d'abord, vous échangez votre jeton client et un identifiant utilisateur (UUID client) contre un jeton d'accès via REST ; ensuite, vous configurez votre client GraphQL avec ce jeton pour effectuer des requêtes API authentifiées.
Ce guide explique comment implémenter l'authentification, stocker les informations d'identification en toute sécurité et configurer vos clients GraphQL et WebSocket pour les fonctionnalités en temps réel.
Prérequis
Avant de vous authentifier, assurez-vous de disposer des éléments suivants :
Jeton client — Un jeton unique pour votre agent (obtenu dans la section Développeur de votre espace de travail Swiftask)
UUID client — Un identifiant unique pour chaque utilisateur ou session (généré côté client)
Bibliothèque client GraphQL — Apollo Client ou un client GraphQL similaire (déjà installé)
Obtenir votre jeton client
Connectez-vous à votre espace de travail Swiftask
Accédez à la section Développeur de votre agent
Recherchez la zone Accès API et copiez votre jeton d'accès (
clientToken)Conservez ce jeton en lieu sûr ; il identifie votre agent auprès de l'API
Pour commencer
Voici la configuration minimale pour authentifier et créer un client GraphQL :
Étape 1 : Générer un UUID client
L'UUID client identifie de manière unique un utilisateur ou une session côté client. Générez-le une seule fois et conservez-le pour plus de persistance.
// Method 1: Using the browser Crypto API (recommended)
const clientUuid = crypto.randomUUID();
localStorage.setItem('swiftask_client_uuid', clientUuid);
// Method 2: Using the uuid library (if installed)
import { v4 as uuidv4 } from 'uuid';
const clientUuid = uuidv4();
localStorage.setItem('swiftask_client_uuid', clientUuid);
// Retrieve on subsequent visits
const storedUuid = localStorage.getItem('swiftask_client_uuid') || crypto.randomUUID();
Étape 2 : Appelez le point de terminaison d'authentification REST
Échangez votre jeton client et votre UUID contre un jeton d'accès.
const clientToken = 'your_agent_client_token';
const clientUuid = localStorage.getItem('swiftask_client_uuid') || crypto.randomUUID();
const response = await fetch(`https://graphql.swiftask.ai/public/widget-bot/${clientToken}`, {
method: 'GET',
headers: {
'x-client-uuid': clientUuid,
'Content-Type': 'application/json',
},
});
const result = await response.json();
if (result.success) {
const { accessToken, botSlug, todoId, workspaceId, starterSessionId } = result.data;
console.log('Authentication successful');
} else {
console.error('Authentication failed:', result.error);
}
Étape 3 : Configurez votre client GraphQL
Utilisez l'accessTokene et l'workspaceIde de la réponse d'authentification pour configurer Apollo Client.
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
const httpLink = createHttpLink({
uri: 'https://graphql.swiftask.ai/graphql',
});
const authLink = setContext((_, { headers }) => {
return {
headers: {
...headers,
authorization: `Bearer ${accessToken}`,
'x-workspace-id': workspaceId, // Required for request routing
'x-client': 'widget', // Identifies this as a public widget client
},
};
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
});
Comprendre la réponse d'authentification
Le point de terminaison REST renvoie un objet de configuration contenant tout ce dont vous avez besoin pour continuer :
Enregistrez ces valeurs ; vous les utiliserez pour les appels API suivants.
Configuration de WebSocket pour les fonctionnalités en temps réel
Si vous prévoyez d'utiliser des abonnements (diffusion de messages en temps réel, événements d'appel d'outils, etc.), configurez une connexion WebSocket en plus de votre client HTTP GraphQL.
import { WebSocketLink } from '@apollo/client/link/ws';
import { split } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
const wsLink = new WebSocketLink({
uri: 'wss://graphql.swiftask.ai/graphql',
options: {
reconnect: true,
connectionParams: {
authorization: `Bearer ${accessToken}`,
workspaceId: workspaceId, // Required for WebSocket routing
},
},
});
// Split: queries/mutations use HTTP, subscriptions use WebSocket
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription';
},
wsLink,
authLink.concat(httpLink)
);
const client = new ApolloClient({
link: splitLink,
cache: new InMemoryCache(),
});
Classe d'authentification complète
Voici une classe réutilisable qui gère l'ensemble du flux d'authentification et la configuration du client :
class SwiftaskAuthClient {
constructor(clientToken, apiUrl = 'https://graphql.swiftask.ai') {
this.clientToken = clientToken;
this.apiUrl = apiUrl;
this.clientUuid = this.getOrCreateClientUuid();
this.config = null;
this.client = null;
}
getOrCreateClientUuid() {
let uuid = localStorage.getItem('swiftask_client_uuid');
if (!uuid) {
uuid = crypto.randomUUID();
localStorage.setItem('swiftask_client_uuid', uuid);
}
return uuid;
}
async authenticate() {
const response = await fetch(
`${this.apiUrl}/public/widget-bot/${this.clientToken}`,
{
method: 'GET',
headers: {
'x-client-uuid': this.clientUuid,
'Content-Type': 'application/json',
},
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error?.message || 'Authentication failed');
}
const result = await response.json();
if (!result.success) {
throw new Error('Authentication failed');
}
this.config = result.data;
return this.config;
}
setupGraphQLClient() {
if (!this.config) {
throw new Error('Not authenticated. Call authenticate() first.');
}
const httpLink = createHttpLink({
uri: `${this.apiUrl}/graphql`,
});
const authLink = setContext((_, { headers }) => ({
headers: {
...headers,
authorization: `Bearer ${this.config.accessToken}`,
'x-workspace-id': this.config.workspaceId,
'x-client': 'widget',
},
}));
const wsLink = new WebSocketLink({
uri: `wss://graphql.swiftask.ai/graphql`,
options: {
reconnect: true,
connectionParams: {
authorization: `Bearer ${this.config.accessToken}`,
workspaceId: this.config.workspaceId,
},
},
});
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription';
},
wsLink,
authLink.concat(httpLink)
);
this.client = new ApolloClient({
link: splitLink,
cache: new InMemoryCache(),
});
return this.client;
}
getClient() {
if (!this.client) {
throw new Error('GraphQL client not initialized. Call setupGraphQLClient() first.');
}
return this.client;
}
getConfig() {
return this.config;
}
}
// Usage
const authClient = new SwiftaskAuthClient('your_client_token');
await authClient.authenticate();
const client = authClient.setupGraphQLClient();
Gestion des erreurs d'authentification
Le point de terminaison REST peut renvoyer des erreurs. Gérez-les avec élégance :
const authenticateWithErrorHandling = async (clientToken, clientUuid) => {
try {
const response = await fetch(
`https://graphql.swiftask.ai/public/widget-bot/${clientToken}`,
{
headers: { 'x-client-uuid': clientUuid },
}
);
if (!response.ok) {
const error = await response.json();
switch (response.status) {
case 400:
throw new Error('Invalid request: Check your parameters');
case 401:
throw new Error('Authentication failed: Invalid client token');
case 403:
throw new Error('Access denied: Agent may not be public');
case 404:
throw new Error('Agent not found');
case 500:
throw new Error('Server error: Try again later');
default:
throw new Error(`Unknown error: ${response.status}`);
}
}
return await response.json();
} catch (error) {
if (error instanceof TypeError) {
throw new Error('Network error: Check your connection');
}
throw error;
}
};
Bonnes pratiques
Stockez l'UUID du client de manière permanente — Enregistrez-le toujours dans localStorage ou un stockage équivalent afin que le même utilisateur soit reconnu d'une session à l'autre.
Protégez votre jeton client — Ne l'exposez jamais dans les référentiels de code côté client. Utilisez des variables d'environnement ou des proxys backend sécurisés en production.
Traitez le jeton d'accès comme une information sensible — Stockez-le de manière sécurisée et ne l'enregistrez jamais dans la console en production.
Implémentez une logique de rafraîchissement des jetons — Les jetons peuvent expirer. Vérifiez la date d'expiration du jeton et rafraîchissez-le si nécessaire.
Utilisez HTTPS/WSS en production — Utilisez toujours des connexions sécurisées pour l'authentification et les fonctionnalités en temps réel.
Gérez les erreurs réseau avec élégance : implémentez une logique de réessai avec un délai exponentiel pour les échecs transitoires.
Validez la structure de la réponse : vérifiez toujours que la réponse d'authentification contient les champs attendus avant de les utiliser.