Closed stjepan closed 7 years ago
I don't have a solution for you. Is it just localStorage, or is sessionStorage also broken in these scenarios? I see why localStorage is blocked, but at least they could make it "go away" after the incognito window is closed. Seems like a very bad choice in the browsers.
If you don't want to have it persist in the browser, as that is what it is sounding like, you could fallback to anysort of database of your liking... Else just change it to public mode...?!?!
@brockallen localStorage and sessionStorage are basically the same, but in one case and that is sessionStorage clears out as soon as you close tab/browser. @GDehnke-Turpin The last options is cookies (in browser), which would work, but there is no official userStore in the solution. I know other fixed it that way, or by preserving it on the server, as you mention. https://github.com/IdentityModel/oidc-client-js/issues/269#issuecomment-303934113
Yea, I'm fully aware. My point was that the incognito window could provide localStorage that was actually implemented similar to sessionStorage -- that would be better than it not working at all.
I got it solved by implementing Secure Cookie Storage, if no other possible.
When in Private Mode, in Safari (both iOS and MacOS), localStorage and sessionStorage have length of 0, which will effectivelly throw an error as soon as you try to store anything.
MDN has a nice feature-detection function that can be used before you try writing to it. https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
Closing. If you still have issues, feel free to reopen.
👍🏻 The current solutions of yours doesn't work when in private/incognito mode. My solution (with a help from another user) is by impl. secure cookie storage.
@stjepan would you mind pointing me in the direction of your solution?
@nbrady-techempower Sure!
import Cookies from 'js-cookie';
const options = {
secure: true
};
export default class CookieStorage {
setItem = (key, value) => Cookies.set(key, value, options);
getItem = key => Cookies.get(key, options);
removeItem = key => Cookies.remove(key, options);
key = index => {
let allKeys = Object.keys(Cookies.getJSON());
return index > -1 && index <= allKeys.length
? allKeys[index]
: '';
};
}
const storageAvailable = type => {
try {
var storage = window[type],
x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
}
catch(e) {
return e instanceof DOMException && (
// everything except Firefox
e.code === 22 ||
// Firefox
e.code === 1014 ||
// test name field too, because code might not be present
// everything except Firefox
e.name === 'QuotaExceededError' ||
// Firefox
e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
// acknowledge QuotaExceededError only if there's something already stored
storage.length !== 0;
}
}
export default storageAvailable;
import CookieStorage from './CookieStorage';
import storageAvailable from './storageAvailable';
export default class StorageFactory {
static getStorage = () => storageAvailable('sessionStorage')
? sessionStorage
: storageAvailable('localStorage')
? localStorage
: new CookieStorage();
}
import { createUserManager } from 'redux-oidc';
import { WebStorageStateStore } from 'oidc-client';
import StorageFactory from './StorageFactory';
const userManagerConfig = {
client_id: "your client id",
redirect_uri: "your redirect uri",
response_type: 'id_token',
scope: 'openid',
authority: "your authority",
ui_locales: "your supported locales",
userStore: new WebStorageStateStore({ store: StorageFactory.getStorage() }),
stateStore: new WebStorageStateStore({ store: StorageFactory.getStorage() }),
};
const userManager = createUserManager(userManagerConfig);
export default userManager;
So, make sure you configure your userManager by overriding userStore and stateStore with the newly StorageFactory. It will check (with help of storageAvailable function, that I got from MDN) if client has support of session or local storage. If not, then it will fallback to the newly defined cookie storage.
Good luck!
Hello @stjepan, Is this still working for you? #631 I tried to change storage similar like you did, but I have an issue with userManager reading from cookie storage. Cheers
Hi,
Unfortunately, I can’t confirm that. We have since then changed the way we’re doing this by tracking on the server side instead (through sessions). This is because of the limitation of storage when in private/incognito mode and/or older browsers that didn’t support either.
If you still wanna try using this, then download the project and see what interface you need to support and adjust the code accordingly.
Best luck!
/S.
On 3 Aug 2018, at 11:07, primozs notifications@github.com wrote:
Hello @stjepan, Is this still working for you? #631 I tried to change storage similar like you did, but I have an issue with userManager reading from cookie storage. Cheers
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
After clearing the storage in chrome -> all options checked -> clear site date, the local/session storage is working again also in incognito mode (at least in chrome 69 ).
@ghenadiibatalski It is good to know your audience so that you can do a proper check on all browsers and devices. For us, this wasn't good enough, since we wanted to support ALL of our current customers (we did a rewrite and we didn't want our current customers to not being able to use the web page as before). And some of those were using elderly devices running Android that didn't played well with this.
Hi,
I see there are following user stores in the code: WebStorageStateStore and InMemoryWebStorage. When users are browsing in private mode, localStorage and sessionStorage are not accessable. InMemory is not usable since a reload would clear that one instantly as well.
What is your proposed workaround for that, so that I still can use your library?
Thanks in advance!
/Stjepan.
Sames as #269