Closed DavidLozzi closed 4 years ago
@DavidLozzi - Thanks for the report. This feels more like the scope of okta-auth-js (which is used by okta-react), but I'll leave this ticket here until we can dig a little deeper and make sure our suggestion works.
@swiftone do I need to do anything to get that team's attention?
@DavidLozzi Store cross-domain cookies is not in our support scope right now. But you can always provide a custom storage provider with a custom implementation instead of an option string (like cookie
).
For the implementation, you can follow the current cookie storage implementation with providing extra domain option.
That custom storage provider looks like exactly what we'd need! Thank you!
@shuowu A new problem has come up, it appears that when I change the storage option, I am now not getting the access token from Okta. If I remove this, I get it in localStorage, add it, I only get idToken in the cookie...
Went from
export default new AuthService({
history,
issuer: CONFIG.OKTA.ISSUER,
pkce: false,
clientId: CONFIG.OKTA.CLIENT_ID,
redirectUri: `${window.location.origin}${CONFIG.OKTA.REDIRECT_URL}`,
tokenManager: { expireEarlySeconds: (30 * 60) }
});
to
export default new AuthService({
history,
issuer: CONFIG.OKTA.ISSUER,
pkce: false,
clientId: CONFIG.OKTA.CLIENT_ID,
redirectUri: `${window.location.origin}${CONFIG.OKTA.REDIRECT_URL}`,
tokenManager: {
expireEarlySeconds: (30 * 60),
storage: {
getItem: (key) => {
try {
console.log('get', key);
console.log(Cookies.get(key));
return Cookies.get(key);
} catch (e) {
console.error('OKTA getItem', e);
}
},
setItem: (key, val) => {
try {
let options = { expires: 1 };
console.log('set', key, val); // I do not see accessToken in the val
Cookies.set(key, val, options);
} catch (e) {
console.error('OKTA setItem', e);
}
}
}
}
});
@DavidLozzi Right, the custom storage provider is a replacement of the default implementation. From the issue, looks like you are storing tokens in cookies, if you want tokens be available in both cookies and localStorage, you can add store to localStorage logic in the custom storage provider.
Sorry for the confusion @shuowu . I don't want it in localStorage, just the cookie. When I remove my config, it uses localStorage. Also, when i try storage: 'cookie'
it works as expected.
When I use a custom storage provider, it DOES save the idToken
but DOES NOT save the accessToken
, i don't even see accessToken
being set.
Cookie has it's size limit, it might because that the accessToken is too big to be stored in cookie. One thing you can try is to delete token.value
before saving it into cookie.
Also, here is the default cookie storage implementation https://github.com/okta/okta-auth-js/blob/master/lib/TokenManager.ts#L230
Thanks @shuowu , that makes sense, thanks for the code, I'll check it out
@shuowu sorry for the firing of posts. I don't get accessToken
in the setItem
function to be able to parse it out.
from above
setItem: (key, val) => {
try {
let options = { expires: 1 };
console.log('set', key, val); // I do not see accessToken in the val
Cookies.set(key, val, options);
} catch (e) {
the val
that is being provided to this function does not contain accessToken
, so I can't split idToken
and accessToken
into separate cookies.
@shuowu I stand corrected, I added the code from your example and I do see okta-token-storage_accessToken
as a cookie. I think I misunderstood how the storage provider works. Adding the get piece now but it's looking promising.
@shuowu Hope I'm not being too hasty, but it's working! Thank you! Closing for now.
@shuowu Sorry to reopen, but a very related issue. I am using the custom storage provider (code below) and it works great on localhost, with our 24hour token expiration. When we move the same to our Dev and QA environments, we get 2hour expiration. When we were using localStorage we were getting 24hr, but switching to custom storage provider gets us 2hrs, except for localhost, gets us 24hrs.
Thoughts on what might cause this? Doesn't seem like the storage provider should be impacting that.
storage: {
getItem: (key) => {
try {
const allCookies = Cookies.get();
const value = {};
Object.keys(allCookies).forEach((k) => {
if (k.indexOf(key) === 0) {
value[k.replace(`${key}_`, '')] = JSON.parse(allCookies[k]);
}
});
// console.log('get', key);
// console.log(value);
return JSON.stringify(value);
} catch (e) {
console.error('OKTA tokenManager storage getItem', e);
return null;
}
},
setItem: (key, val) => {
try {
let options = { expires: 1 };
if (CONFIG.ENVIRONMENT !== 'local') { // localhost has some restrictions
options = Object.assign(options, { secure: true, domain: '.domain.com' });
}
// console.log('set', key, val);
const value = JSON.parse(val);
Object.keys(value).forEach((k) => {
const storageKey = `${key}_${k}`;
delete value[k].value; // unncessary and makes cookie heavy
Cookies.set(storageKey, value[k], options);
});
} catch (e) {
console.error('OKTA tokenManager storage setItem', e);
}
}
}
To clarify, I am using the expiresAt
value from the accessToken
to determine when it expires, taking that value and creating a date, like new Date(JSON.parse(getCookie('okta-token-storage_accessToken')).expiresAt * 1000)
@DavidLozzi From the code, I don't see issues. You probably can check if there is any special cookie rule has been set in your DEV/QA envs. Also, this link may help: https://github.com/js-cookie/js-cookie/wiki/Frequently-Asked-Questions#how-to-make-the-cookie-expire-in-less-than-a-day
@shuowu It appears to be something in our Okta config, as I reverted our code to 2 days ago and still get the 2hr expiration, no cookies being used. Sorry for the reopen, I thought the only thing that changed was my code, but alas, it appears that's not the case (I'm assuming). Thanks for the response!
I'm submitting this issue for the package(s):
I'm submitting a:
Current behavior
We are widening our program and now including a few different web apps in our solution. We want to store the Okta token in the cookie, but for the domain, like
.domain.com
. Currently, the cookie gets stored inapp.domain.com
, and when we navigate to the next app,web.domain.com
we lose the cookie. Is it possible to configure this to store and retrieve the tokens from.domain.com
instead?Expected behavior
Minimal reproduction of the problem with instructions
Extra information about the use case/user story you are trying to implement
Environment
node -v
):