├── index.php ├── js.cookie.min.js ├── readme.md ├── sessionbox.js ├── start.sh └── user.php /index.php: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /js.cookie.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Minified by jsDelivr using Terser v3.14.1. 3 | * Original file: /npm/js-cookie@2.2.1/src/js.cookie.js 4 | * 5 | * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files 6 | */ 7 | !function(e){var n;if("function"==typeof define&&define.amd&&(define(e),n=!0),"object"==typeof exports&&(module.exports=e(),n=!0),!n){var t=window.Cookies,o=window.Cookies=e();o.noConflict=function(){return window.Cookies=t,o}}}(function(){function e(){for(var e=0,n={};e 45 | 46 | ``` 47 | 48 | The list of all names of cookies used for the user session must be indicated. 49 | Cookies existing from the first connection are indicated by the value `true`. 50 | 51 | ```javascript 52 | var sessionbox = new SessionBox({ 53 | 'COOKIE1': true, 54 | 'COOKIE2': false 55 | }); 56 | ``` 57 | 58 | #### Update and iFrame 59 | 60 | A cookie can be saved afterwards (in case of a later connection via iFrame), but must have been declared beforehand (see above): 61 | 62 | ```javascript 63 | sessionbox.save('COOKIE2'); 64 | ``` 65 | 66 | #### Logout 67 | 68 | Logging out, i.e. deleting cookies, can only be done from SessionBox : 69 | 70 | ```javascript 71 | sessionbox.close(); 72 | ``` 73 | 74 | ### Démo 75 | 76 | ```sh 77 | ./start.sh 78 | ``` 79 | 80 | http://localhost:8000 81 | 82 | ## Contact 83 | 84 | [Emmanuel ROECKER](https://www.rymetemmanuel.fr/emmanuel-roecker.html) 85 | 86 | ## Français 87 | 88 | Les sites internet utilisent généralement les cookies pour enregistrer l'id unique de l'utilisateur qui permet de l'identifier 89 | sans devoir lui redemander son login/password à chaque requête. 90 | 91 | Les cookies appartiennent à un nom de domaine. 92 | 93 | Dans un navigateur classique (sans mode privé activé), on ne peut se connecter avec le même navigateur 94 | sur plusieurs comptes utilisateurs d'un même site internet. 95 | 96 | Pour permettre de se connecter sur plusieurs comptes utilisateurs, il existe une solution de contournement 97 | en isolant les cookies par onglet du navigateur. 98 | 99 | Le principe est de sauvegarder les cookies dans le [sessionStorage](https://developer.mozilla.org/fr/docs/Web/API/Window/sessionStorage) 100 | et de les restorer automatiquement lorsque l'onglet est affiché ou avant de changer de page web. 101 | 102 | La contrainte est que l'on ne peut se déconnecter d'un compte utilisateur sans utiliser la fonction `SessionBox.close()`. 103 | 104 | ### Côté serveur 105 | 106 | Il faut s'assurer qu'un nouvel id utilisateur est créé lors de l'identification de l'utilisateur (même si un cookie existe déjà) 107 | 108 | Un exemple en PHP : 109 | 110 | ```PHP 111 | session_name('COOKIE1'); 112 | $newid = session_create_id(); 113 | session_id($newid); 114 | session_start(); 115 | ``` 116 | 117 | ### Côté client 118 | 119 | #### Initialisation 120 | 121 | Le projet dépand de [js-cookie](https://github.com/js-cookie/js-cookie) pour la gestion des cookies. 122 | 123 | ```html 124 | 125 | 126 | ``` 127 | 128 | La liste de tous les noms des cookies utilisés pour la session utilisateur doivent être indiqués. 129 | Les cookies existant dès la première connexion sont indiqués par la valeur `true`. 130 | 131 | ```javascript 132 | var sessionbox = new SessionBox({ 133 | 'COOKIE1': true, 134 | 'COOKIE2': false 135 | }); 136 | ``` 137 | 138 | #### Mise à jour et iFrame 139 | 140 | Un cookie peut être par la suite sauvegardé (cas d'une connexion ultérieure par iFrame), mais doit avoir été déclaré auparavant (voir ci-dessus) : 141 | 142 | ```javascript 143 | sessionbox.save('COOKIE2'); 144 | ``` 145 | 146 | #### Déconnexion 147 | 148 | La déconnexion, c'est à dire la suppression des cookies ne peut être effectués qu'à partir de SessionBox : 149 | 150 | ```javascript 151 | sessionbox.close(); 152 | ``` 153 | 154 | ### Démo 155 | 156 | ```sh 157 | ./start.sh 158 | ``` 159 | 160 | http://localhost:8000 161 | 162 | ## Contact 163 | 164 | [Emmanuel ROECKER](https://www.rymetemmanuel.fr/emmanuel-roecker.html) 165 | 166 | -------------------------------------------------------------------------------- /sessionbox.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SessionBox 3 | * 4 | * Javascript 5 | * 6 | * @author Emmanuel ROECKER 7 | * @license MIT 8 | * 9 | * Created : 18/01/2021 10 | * File : sessionbox.js 11 | * 12 | */ 13 | 14 | var SessionBox = (function () { 15 | function SessionBox(cookies) { 16 | if ((cookies === null) || (typeof cookies !== 'object')) { 17 | console.error("Parameters must be an object (Example : {'cookie1':true,'cookie2':false})"); 18 | return; 19 | } 20 | 21 | var hidden, visibilityChange; 22 | if (typeof document.hidden !== "undefined") { 23 | hidden = "hidden"; 24 | visibilityChange = "visibilitychange"; 25 | } else if (typeof document.msHidden !== "undefined") { 26 | hidden = "msHidden"; 27 | visibilityChange = "msvisibilitychange"; 28 | } else if (typeof document.webkitHidden !== "undefined") { 29 | hidden = "webkitHidden"; 30 | visibilityChange = "webkitvisibilitychange"; 31 | } 32 | 33 | if (typeof document.addEventListener === "undefined" || 34 | typeof document.hidden === "undefined" || 35 | typeof sessionStorage === "undefined") { 36 | console.error("Requires a browser that supports Session Storage and Page Visibility API."); 37 | return; 38 | } 39 | 40 | if (Cookies === null) { 41 | console.error('Javacript Cookie library dependancy (https://github.com/js-cookie/js-cookie)'); 42 | return; 43 | } 44 | 45 | this.prefix = "sessionbox-"; 46 | this.cookies = cookies; 47 | 48 | if (sessionStorage.getItem(this.prefix + 'closed')) { // a tab cannot be reused if logout 49 | this.restore(); 50 | document.location.reload(); 51 | } 52 | 53 | for (var cookiename in cookies) { 54 | if (cookies[cookiename]) 55 | this.save(cookiename); 56 | } 57 | 58 | var _this = this; 59 | window.onbeforeunload = function () { // for cookies deleted or expired 60 | _this.restore(); 61 | }; 62 | document.addEventListener("visibilitychange", function () { // for ajax requests 63 | if (!document.hidden) { 64 | _this.restore(); 65 | } 66 | }, false); 67 | this.restore(); // deleted unused cookies 68 | } 69 | 70 | SessionBox.prototype.save = function (cookiename) { 71 | if (!(cookiename in this.cookies)) { 72 | console.error(cookiename + " not exist"); 73 | return; 74 | } 75 | var sessionid = Cookies.get(cookiename); 76 | if (sessionid) 77 | sessionStorage.setItem(this.prefix + cookiename, sessionid); 78 | }; 79 | 80 | SessionBox.prototype.close = function () { 81 | sessionStorage.setItem(this.prefix + 'closed', 'true'); 82 | for (var cookiename in this.cookies) { 83 | sessionStorage.removeItem(this.prefix + cookiename); 84 | }; 85 | this.restore(); 86 | }; 87 | 88 | SessionBox.prototype.restore = function () { 89 | for (var cookiename in this.cookies) { 90 | var sessionid = sessionStorage.getItem(this.prefix + cookiename); 91 | if (sessionid) { 92 | Cookies.set(cookiename, sessionid); 93 | } else { 94 | Cookies.remove(cookiename); 95 | } 96 | }; 97 | }; 98 | 99 | return SessionBox; 100 | })(); -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | php -S localhost:8000 3 | -------------------------------------------------------------------------------- /user.php: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 29 |
30 |
31 | 34 | 35 | 36 | 43 | 44 | 45 | 50 | 51 | 52 | --------------------------------------------------------------------------------