sockjs / sockjs-client

WebSocket emulation - Javascript client
MIT License
8.45k stars 1.3k forks source link

Support for setting withCredential true/false #257

Open divakarray opened 9 years ago

divakarray commented 9 years ago

I can find that noCredentials flag with option does set withCredential true/false but it doesn't work.

Are there any other ways or documentation will help me to set the parameter noCredentials flag true/false with request.

brycekahle commented 9 years ago

I'm a bit confused as to what you are asking for. The withCredentials flag on XHRs will get set automatically based on whether the request is cross-domain.

divakarray commented 9 years ago

I want to make cross domain request with the parameter withcredential false. Will it be possible?

Thanks. On 10 Aug 2015 22:24, "Bryce Kahle" notifications@github.com wrote:

I'm a bit confused as to what you are asking for. The withCredentials flag on XHRs will get set automatically based on whether the request is cross-domain.

— Reply to this email directly or view it on GitHub https://github.com/sockjs/sockjs-client/issues/257#issuecomment-129525057 .

brycekahle commented 9 years ago

There currently is not an option to set withCredentials to false. I can work on adding that, but I would also accept a PR.

divakarray commented 9 years ago

Thanks, but any plans for which release this issue will be resolved?

brycekahle commented 9 years ago

Can you help me understand your use case? That might bump this up in priority.

divakarray commented 9 years ago

if server response header is having the parameter Access-Control-Allow-Origin as * then it doesn't need to have withCredentials true.

withCredential parameter required only when Access-Control-Allow-Origin in response header is a specific IP/HOST.

brycekahle commented 9 years ago

Sure, it is not required, but it also doesn't hurt anything.

brycekahle commented 8 years ago

Closing for now. If you can provide me with a use case where you need withCredentials to be false, then I will reopen this issue.

hgwood commented 8 years ago

Sure, it is not required, but it also doesn't hurt anything.

Actually, Chrome will refuse to deliver the response to the calling JS: A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true..

hgwood commented 8 years ago

I'm new to this kind of CORS and CSRF issues so I might not understand correctly, but according to this:

In order to reduce the chance of CSRF vulnerabilities in CORS, CORS requires both the server and the client to acknowledge that it is ok to include cookies on requests. Doing this makes cookies an active decision, rather than something that happens passively without any control.

It sounds like I don't want withCredentials to be true unless I am positive I really need it. However, SockJS seems to force it true for all cross-domain XHRs.

brycekahle commented 8 years ago

@hgwood It also requires Access-Control-Allow-Credentials, which we do not set if set Access-Control-Allow-Origin is *.

hgwood commented 8 years ago

@brycekahle It does. Thank you for answering. I did not meant to imply that SockJS does something that is a security liability, just that according to this quote, it implicitly does something that the application developer should explicitly choose to do.

Also you are assuming that the client is trusting the server. What if I'm developing a client that connects to 3rd party servers (public APIs)? Then SockJS forces me to accept cookies from these parties, doesn't it? (Again, I'm learning here.)

If I'm developing a client-server pair, then it forces my server to have Access-Control-Allow-Origin not equal to *.

Wouldn't that be 2 things a developer would like to control? However I don't know why SockJS does it so there might be an advantage here that I don't understand :). The code comes with a comment saying:

// Mozilla docs says https://developer.mozilla.org/en/XMLHttpRequest :
// "This never affects same-site requests."
this.xhr.withCredentials = 'true';

But then this line is only executed for cross-site requests, so I'm a bit confused.

nylen commented 8 years ago

+1 for re-opening and fixing this issue. My Node.js server is running on a different domain than my localhost development setup. To allow API requests I'm using SockJS and the cors package as follows:

sockjsServer.installHandlers(server, { prefix : '/sockjs' });
app.use(cors());

This leads to the following error in the browser (Chrome):

A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost:3010' is therefore not allowed access.

I've found 2 ways to work around it. The first is on the server side:

app.use(cors({ origin : true, credentials : true }));

This may not be desirable or possible depending on the server setup.

The second way is to monkey-patch SockJS on the client side, taking advantage of the fact that AbstractXHRObject#_start is never called with an opts parameter:

import AbstractXHRObject from 'sockjs-client/lib/transport/browser/abstract-xhr';

const _start = AbstractXHRObject.prototype._start;

AbstractXHRObject.prototype._start = function(method, url, payload, opts) {
    if (!opts) {
        opts = { noCredentials : true };
    }
    return _start.call(this, method, url, payload, opts);
};
brycekahle commented 8 years ago

@nylen What version of the sockjs-node server are you using? It handles CORS for you.

nylen commented 8 years ago

Latest - 0.3.17

I still need to set up CORS for other things on this server (some JSON endpoints).

brycekahle commented 8 years ago

@nylen you shouldn't apply the cors middleware to the sockjs routes then.

nylen commented 8 years ago

redmountainmakers/kilntroller-server@e482663 - that makes sense, and works without the hacks. Thanks!

modoulo commented 6 years ago

Hi this is the first time I use your biblioteque with angular and spring. the client and the server are running on two different domains. when running the client I am confronted with an error on chrome that says:

Failed to load http://localhost:8090/socket/info?t=1525354386425: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:4200' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

I wanted to know if the problem was solved. thank you

nylen commented 6 years ago

Hi @modoulo, I think if you can set Access-Control-Allow-Origin to localhost:4200 (the URL for your client app) then this should work as expected.

modoulo commented 6 years ago

@nylen I already did it but it still does not work. Finally I commented on the line:

// Mozilla docs says https://developer.mozilla.org/en/XMLHttpRequest:
// "This never affects same-site requests."
  this.xhr.withCredentials = true;

as indicate in this url https://github.com/sockjs/sockjs-client/issues/416 and it works. but I do not know if it's a good thing or not.

Xaber20110202 commented 5 years ago

@nylen 's way is pretty good.

Or we can set nginx header 'Access-Control-Allow-Origin: $http_origin';

ttimot24 commented 3 years ago

Is there any working solution for this, it took away 3 hours to get around this problem, and still not getting closer. Why is it so hard to make this property configurable?

dorantor commented 3 years ago

What would be a proper way to work around mentioned problem in case when I'm connecting to server I don't control and it always answering with

access-control-allow-origin: *

So Chrome is complaining that The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute. And, ofc, I'm connecting from other|different domain than the server. Currently it's localhost, later it will be some other domain. I assume that I might be able to change include to something different, but cannot see how. And I cannot find any documentation where this possibility described. I went through all links in this thread and it seems the only way is to tamper with local copy of the library. But it doesn't feel good. Are there any other options?

wzshuang commented 1 year ago

+1 for re-opening and fixing this issue.

5452 commented 4 months ago

this issue has been opened so long and not solved yet? looking forward ...

weihong1028 commented 4 months ago

Nice,thank you!                               ——weihong

nab138 commented 4 months ago

+1, please fix this

axten commented 1 month ago

still an issue for us

weihong1028 commented 1 month ago

Nice,thank you!                               ——weihong