-
Notifications
You must be signed in to change notification settings - Fork 250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't reference window in default options if it doesn't exist #73
base: master
Are you sure you want to change the base?
Don't reference window in default options if it doesn't exist #73
Conversation
Is this working, have you tested this? What about this window reference? https://github.com/dgrubelic/vue-authenticate/blob/master/src/oauth/popup.js#L21 |
I tested it locally, though only for relatively limited usecases so far... the thing is, for any code that is running interactively in response to user action (e.g. open popup) it will be run on client no matter what and it's fine. The problem is more for things loaded at javascript parse time (e.g. options are loaded on import) |
src/options.js
Outdated
@@ -13,7 +13,7 @@ export default { | |||
storageType: 'localStorage', | |||
storageNamespace: 'vue-authenticate', | |||
cookieStorage: { | |||
domain: window.location.hostname, | |||
domain: typeof(window) === 'undefined' ? '' : window.location.hostname, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use isUndefined
or isDefined
helper inside utils.js
and extract this into a helper function like getCookieDomainUrl()
.
src/options.js
Outdated
@@ -55,7 +55,7 @@ export default { | |||
name: 'facebook', | |||
url: '/auth/facebook', | |||
authorizationEndpoint: 'https://www.facebook.com/v2.5/dialog/oauth', | |||
redirectUri: window.location.origin + '/', | |||
redirectUri: typeof(window) === 'undefined' ? '/' : window.location.origin + '/', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of repeated work here. Again, use isUndefined
or isDefined
helper and extract this into a helper function like getRedirectUri(uri)
where you check if window is defined. If false, return uri or null. If true, return window.location.origin
+ append uri.
Updated! |
src/options.js
Outdated
@@ -55,7 +60,7 @@ export default { | |||
name: 'facebook', | |||
url: '/auth/facebook', | |||
authorizationEndpoint: 'https://www.facebook.com/v2.5/dialog/oauth', | |||
redirectUri: typeof(window) === 'undefined' ? '/' : window.location.origin + '/', | |||
redirectUri: getCookieDomainUrl('/'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not good. You are using window.location.hostname
for redirectUri. That information is only "{domain_name}.{TLD}" => "github.com". This means that if you have site on https, if you setup only hostname as your redirectUri
, you will be redirected to http version of the site.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack good point, this time around missed the distinction that we were using hostname in just the first domain, origin in the rest. Fixing.
45a9f6d
to
77976c8
Compare
src/options.js
Outdated
return isUndefined(window) ? '' : `${window.location.hostname}`; | ||
} | ||
|
||
function getCookieDomainUrl(path = '') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Contextually, you are not returning CookieDomainUrl
but redirectUri
, so getRedirectUri
would be a much better name for this function.
I did some additional testing this afternoon after updating where my build was referencing, and found that for some reason using |
Also starting to get deeper in and wanting to actually do more auth on the server side & not just make sure we don't break and then do auth on client... I think the primary blocker for this using cookie store is not having server-side access to cookies (it checks for It's a single file with no deps, so if you like we could even copy it in... |
No, this will not solve SSR problem because this library you suggested is only used for parsing and serialization in cookie format, but it doesn't actually sets the cookie into the document which will make it persistant. What is actually the problem is All you need to do is to add |
I don't think that's all.. the issue is we want to be able to read & write the cookies on the server the same as on the client... (or at least read them; auth change may happen only on client, but server needs to be able to read...) _getCookie needs to understand how to read cookies on server side. Right now it always returns unauthed |
Ok, finally had time to really dig my teeth into the question of auth on server side, and realized where I'd had the gap... To remedy this, I updated the cookieOptions to allow passing in your own function to get cookies, so the server can pass a function that is bound with the appropriate context (e.g the I don't think we need to do the same thing for writing cookies, as that interaction is likely always on the client, but we could use this same approach if you think it's relevant. |
@@ -1,3 +1,6 @@ | |||
import { getCookieDomain, getRedirectUri } from './utils.js'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two functions are contextually highly connected only to options.js
file and nowhere else. There is no reason they should be located in utils.js
file. Please move them back in options.js
file.
expires: null, | ||
path: '/', | ||
secure: false | ||
secure: false, | ||
getCookieFn: this._getCookie, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't have time to think about this logic these past few days, but my first impression is that I don't like it too much. The main reason is that the ability to authenticate a user on the server side is by using cookies. I will have to think a bit more about this.
For now, I suggest that you make it compilable in SSR, and later we can try to think about a solution to persist authentication state over SSR.
As a temporary solution, possibly can be helpful this component which wraps non SSR friendly components (excludes from SSR and renders only on client-side) |
I'm setting up a nuxt.js app with vue-authenticate, which involves having server-side rendering as well as client-side. When we try to do SSR, it breaks when loading the default options due to
window
not existing.I'm fine with overriding these options, but with current implementation it breaks on import, before I even have the chance to override. This changeset fixes that by checking for window before referencing it, and just using empty if it does not.
This is the minimal I need to keep moving forward - so far actually doing all the auth on the client side, I just need it to not break when loading on the server. As I keep going may submit some more PRs to get things working better on the server as well.