Deep Links e Protocol Handler
I deep links permettono di aprire la tua applicazione Electron da URL personalizzati (es. mia-app://open/file). Questo è utile per OAuth, link condivisibili e integrazione con altre applicazioni.
Registrare un Protocollo Personalizzato
Registrazione a Runtime
const { app } = require('electron');
// Registra il protocollo 'mia-app://'
if (process.defaultApp) {
// Durante lo sviluppo
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('mia-app', process.execPath, [
path.resolve(process.argv[1]),
]);
}
} else {
// App distribuita
app.setAsDefaultProtocolClient('mia-app');
}
Dopo la registrazione, gli URL come mia-app://qualcosa apriranno la tua applicazione.
Deregistrare il Protocollo
app.removeAsDefaultProtocolClient('mia-app');
Verificare la Registrazione
const isDefault = app.isDefaultProtocolClient('mia-app');
console.log('Protocollo registrato:', isDefault);
Gestire i Deep Links
Su Windows e Linux
Su queste piattaforme, l’URL viene passato come argomento della command line:
// Gestisci l'URL quando l'app è già aperta (single instance)
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.quit();
} else {
app.on('second-instance', (_event, commandLine) => {
// L'URL è nell'ultimo argomento
const url = commandLine.pop();
handleDeepLink(url);
// Porta la finestra in primo piano
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.focus();
}
});
}
// Gestisci l'URL all'avvio dell'app
app.whenReady().then(() => {
createWindow();
// Controlla se l'app è stata aperta con un deep link
const url = process.argv.find((arg) => arg.startsWith('mia-app://'));
if (url) {
handleDeepLink(url);
}
});
Su macOS
Su macOS, il deep link arriva tramite l’evento open-url:
app.on('open-url', (event, url) => {
event.preventDefault();
handleDeepLink(url);
});
Handler Universale
function handleDeepLink(url) {
try {
const parsed = new URL(url);
const protocol = parsed.protocol; // 'mia-app:'
const host = parsed.hostname; // 'action'
const pathname = parsed.pathname; // '/param1/param2'
const params = parsed.searchParams; // ?key=value
console.log(`Deep link: ${host}${pathname}`);
switch (host) {
case 'open':
// mia-app://open/file?path=/documenti/test.txt
const filePath = params.get('path');
if (filePath) openFile(filePath);
break;
case 'settings':
// mia-app://settings/theme
openSettings(pathname.slice(1));
break;
case 'auth':
// mia-app://auth/callback?token=xxx
const token = params.get('token');
if (token) handleAuthCallback(token);
break;
default:
console.log('Deep link non riconosciuto:', url);
}
} catch (error) {
console.error('URL deep link non valido:', error);
}
}
OAuth con Deep Links
Un caso d’uso comune è il flusso OAuth:
// 1. Apri il browser per l'autenticazione
const { shell } = require('electron');
function startOAuth() {
const authURL = 'https://provider.com/oauth/authorize'
+ '?client_id=APP_ID'
+ '&redirect_uri=mia-app://auth/callback'
+ '&response_type=code';
shell.openExternal(authURL);
}
// 2. Gestisci il callback
function handleAuthCallback(token) {
// Ricevi il token dal deep link mia-app://auth/callback?token=xxx
mainWindow.webContents.send('auth:success', token);
}
Single Instance Lock
Per evitare che vengano aperte più istanze dell’app quando si clicca un deep link:
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
// Un'altra istanza è già in esecuzione
app.quit();
} else {
app.on('second-instance', (_event, commandLine) => {
// Gestisci il deep link dalla seconda istanza
const url = commandLine.find((arg) => arg.startsWith('mia-app://'));
if (url) handleDeepLink(url);
// Porta la finestra esistente in primo piano
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.focus();
}
});
app.whenReady().then(createWindow);
}
Configurazione per la Distribuzione
Windows (electron-builder)
{
"build": {
"win": {
"target": "nsis"
},
"nsis": {
"perMachine": false
},
"protocols": {
"name": "Mia App Protocol",
"schemes": ["mia-app"]
}
}
}
macOS (Info.plist)
Con electron-builder, aggiungi nella configurazione:
{
"build": {
"mac": {
"target": "dmg"
},
"protocols": {
"name": "Mia App Protocol",
"schemes": ["mia-app"]
}
}
}
Sicurezza
- Valida sempre gli URL — non fidarti dei dati nei deep links
- Usa HTTPS per OAuth — mai HTTP per flussi di autenticazione
- Limita le azioni — permetti solo azioni predefinite, non comandi arbitrari
- Sanifica i parametri — tratta i parametri dei deep link come input non fidato