Dans l’article « Angular-ElectronJS – Login API REST jwt », le token de l’utilisateur était enregistré dans son navigateur grâce au localStorage.
Or nous avons comme objectif de créer une application multiplateforme : logiciel de bureau et application web, nous allons ajuster notre code pour répondre à cet objectif.
Nous allons suivre quelques étapes :
- Création d’un service storageService partagé qui enregistre les informations retournées par le serveur :
- soit localStorage (dans le contexte webapplication)
- soit dans un fichier json (dans le contexte electronjs)
- Remplacement des appels de localStorage .
Service storageService
La création de ce service se fait grâce à la commande Angular suivante :
ng g service providers/storage
Les fichiers suivants sont créés :
- angular-electron/src/app/providers/storage.service.ts
- angular-electron/src/app/providers/storage.service.spec.ts
Modifions angular-electron/src/app/providers/login.service.ts et importons le service ElectronService. ElectronService est un service pré-installé dans l’application. Il permet d’utiliser l’API de Electronjs dans une application Angular.
import { StorageService } from './storage.service';
import { ElectronService } from './electron.service';
Ajoutons quelques variables avant le constructeur
public storage: StorageService;
Puis ajoutons dans le constructeur le service ElectronService
constructor(private http: HttpClient, private electron: ElectronService)
Remplaçons toutes les directives localStorage par this.storage dans le fichier angular-electron/src/app/providers/login.service.ts
Ancien Code | Nouveau code |
---|---|
this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.get('user'))); |
this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(this.storage.get('user'))); |
localStorage.setItem('user', JSON.stringify(user)); |
this.storage.save('user', user); |
localStorage.removeItem('user'); |
this.storage.remove('user'); |
return localStorage.getItem('user'); |
return this.storage.get('user'); |
Comme vu un peu plus haut, les informations retournées par le serveur (si l’utilisateur a bien été authentifié) seront enregistrées dans un fichier .json (dans le contexte electronjs). Nous allons enregistrer le « nom de ce fichier » dans le fichier de configuration spécifique à l’environnement utilisé. Rappelons que nous avons choisi les 3 environnements suivants :
- LOCAL
- DEV
- PROD
L’environnement en LOCAL (angular-electron/src/environments/environment.ts) contient le code suivant
export const AppConfig = {
production: false,
environment: 'LOCAL',
apiUrl: 'http://localhost:3008/api',
configFile: 'token.json'
};
La ligne 5 de ce fichier contient le nom du fichier .json. Ce fichier se situe à l’emplacement suivant pour l’OS windows: C:Users~AppDataRoamingangular-electrontoken.json
. L’API de ElectronJs permet de récupérer le chemin de ce fichier. Voici un exemple de cet appel :
this.electron.remote.app.getPath('userData') + '/' + AppConfig.configFile
Le fichier angular-electron/src/app/providers/storage.service.ts contient le code suivant
import { Injectable } from '@angular/core';
import {ElectronService} from "./electron.service";
import { AppConfig } from '../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class StorageService {
isElectron: boolean;
confExists: boolean;
electron: ElectronService;
configFile: string;
constructor(electron: ElectronService) {
this.electron = electron;
if (this.electron.isElectron()) {
this.initElectron();
}
}
save(key: string, content: string) {
if (this.isElectron) {
let data = {};
data[key] = content;
this.electron.fs.writeFileSync(this.configFile, JSON.stringify(data));
return;
}
localStorage.setItem(key, JSON.stringify(content));
}
remove(key: string) {
if (this.isElectron) {
// Remove file
this.electron.fs.unlinkSync(this.configFile);
return;
}
localStorage.removeItem(key);
}
get(key: string) {
if (this.isElectron && this.electron.fs.existsSync(this.configFile)) {
let jsonContents = this.electron.fs.readFileSync(this.configFile, "utf8");
jsonContents = JSON.parse(jsonContents);
return JSON.stringify(jsonContents[key]);
}
return localStorage.getItem(key);
}
private initElectron() {
this.isElectron = true;
this.configFile = this.electron.remote.app.getPath('userData') + '/' + AppConfig.configFile;
this.confExists = this.electron.fs.existsSync(this.configFile);
}
}
save
Si on regarde de près la methode save
qui enregistre les informations retournées par le serveur.
save(key: string, content: string) {
if (this.isElectron) {
let data = {};
data[key] = content;
this.electron.fs.writeFileSync(this.configFile, JSON.stringify(data));
return;
}
localStorage.setItem(key, JSON.stringify(content));
}
La ligne 2-7 vérifie si nous sommes dans le contexte electronjs. Dans ce cas, les informations retournées par le serveur ( token y compris) seront enregistrées dans le fichier json C:Users~AppDataRoamingangular-electrontoken.json
.Ceci est possible grâce à l’API de electronjs qui permet d’enregistrer un fichier sur la machine. Cet API utilise tout simplement l’API fs de nodejs.
this.electron.fs.writeFileSync(this.configFile, JSON.stringify(data));
La ligne 9 est utilisée dans le contexte web application
remove
La methode remove est légèrement différente selon le contexte :
- electronjs: le fichier
C:Users~AppDataRoamingangular-electrontoken.json
sera supprimé. - webapplication: le localstorage contenant la clé user sera supprimé.
get
La méthode get est similaire dans les 2 contextes :
- lire les informations contenus dans localstorage ou dans le fichier json
Et voila, nous avons atteint notre objectif. Notre application multiplateforme fonctionne correctement.
Capture webapplication
Capture electronjsapplication
Sources: https://github.com/rabehasy/angular-electron/tree/step3