I'm facing some issues while trying to work with cookie in distincts domains. In my scenario I have two apps (app1 and app2). Basically, the app1 is doing an ajax request to the app2 in order to this one creates a cookie (i.e. dummyCookie). The app2 is an application running over the Play framework 2.5 for Java. I'm creating the cookie like this:
response().setCookie(Http.Cookie.builder("dummyCookie", "9e0a6b4c-58ed-b700-0000-015ec494956").build());
I'm using the plays's CORSFilter:
package myCustomFilters.filters;
import play.filters.cors.CORSFilter;
import play.http.DefaultHttpFilters;
import javax.inject.Inject;
public class Filters extends DefaultHttpFilters {
#Inject
public Filters(CORSFilter corsFilter) {
super(corsFilter);
}
}
In my application.conf I have this configuration:
play.http.filters = "myCustomFilters.Filters"
play.filters {
cors {
pathPrefixes = ["/"]
allowedOrigins = null
allowedHttpMethods = ["POST, GET, PUT, DELETE, OPTIONS"]
}
}
In the Chrome's console, in the Network tab, I could see the cookie in the response header.
If I check the Application tab, Cookies session, I couldn't see the cookie there:
I did some investigations and maybe the problem is related to the scenario "CORS + AJAX", since that I have one application calling (via ajax request) the another one to generate a cookie.
Guys, somebody already faced with this kind of scenario?
I had similar issues. I had to tweak the configuration in different ways to make that work in Chrome. And client request also need some specific changes (I use JQuery, and this kind of approach was necessary : Sending credentials with cross-domain posts?).
However, in the end, I discovered that Safari would most likely never work for me, as Apple now has specific rules to handle when cookies can be sent cross domain or not. Depending on what you are trying to achieve, this might lead you to consider a totally different approach.
Related
I am building stateless restfull API in Yii2. So I created new APP in my advanced app layout (as preferred by Yii2 creators) and configure all necessary things and API worked.
Now I want to make it stateless - I want to disable session and I want it to be accomplished in config/main.php inside my API app to ensure it as global setting.
Also I want to disable cookies and auto login.
What I have been playing now so far is inside Module class
<?php
namespace api\modules\v1;
use \app\models\User;
use yii\filters\auth\HttpBasicAuth;
class Module extends \yii\base\Module
{
...
public function init()
{
parent::init();
\Yii::$app->user->enableSession = false;
\Yii::$app->user->enableAutoLogin = false;
}
...
}
But when trying to access data using POSTMAN on Chrome I can see that:
Cookies are set (PHPSESSID, _csrf, _identity)
I always get popup asking for username and password
Thanks for your help in advance!
Finally I found out what the problem is. Yii2 worked OK, but Postman had some data stored from the past when cookies and session were enabled. What helped me was deleting browser's history (including cookies), close all instances of browser and rerun.
The main problem about Access-Control-Allow-Origin I think. But when I configure the Web API project as defined in the given documentation, it still not working in chrome and firefox but working in IE well (it is about IE thinks localhost is not cross domain, AFAIK). I tried different ways to make it work but no result.
I put the example project to github repository. Project is very simple. There are two applications working on cross domains. It is very simple chat application like in signalr examples.
You must change the value of api host in client javascript file:
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApp/Scripts/app/chat.js#L2
When you open the Chat page in mvc project, there will be two requests to api application
1- Regular ajax request (which is working fine)
2- Signalr negotiate request (cancelled)
And also I don't think browser disables the CORS because of if it disables there would not be an hit to server. So I think it is about browser but not about browser disables (something else).
Details are in repository
Readme: https://github.com/yusufuzun/WebApiSignalR/blob/master/README.md
Fiddler Results: https://github.com/yusufuzun/WebApiSignalR/blob/master/FiddlerResults
The bad part about it also is server returning 500 with this error:
System.InvalidOperationException: 'chat' Hub could not be resolved.
Which hub name is chat also.
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Hubs/ChatHub.cs#L10
You can enable CORS for Web Api in project with different ways for test purposes. Each one is giving different errors all about XMLHttpRequest Access-Control-Allow-Origin.
I commented them, so you can uncomment and make test for each one:
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Global.asax.cs#L24
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/App_Start/WebApiConfig.cs#L14
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/App_Start/WebApiConfig.cs#L16
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Controllers/ChatController.cs#L17
So what is going on here?
After I talked with David Fowler in JabbR, he mentioned the thing about using CORS with SignalR. My signalr startup code was wrong. So after changing the startup code like in his advice it worked well.
He also mentioned SignalR and Web API are working with different CORS definitions. So enabling or disabling one doesn't affect other.
Here is the new startup code:
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR(new HubConfiguration()
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true
});
});
The old one:
app.MapSignalR(new HubConfiguration()
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true
}).UseCors(CorsOptions.AllowAll);
Hope it helps to somebody out there.
My current setup is AngularJS + Django 1.5 and I have completely thrown away the use of Django's template engine (ie. the backend is pretty much an API server).
Since I am not using the csrf_token template tag, Django, in turn, does not set and send the csrftoken cookie in response. As instructed by the official docs, the ensure_csrf_cookie() decorator should be used to force the decorated view to send the csrftoken cookie.
I have applied the ensure_csrf_cookie() decorator to the view, which serves the first GET request that my web client calls at bootstrapping. With that, my web client gets a hold of the CSRF token and henceforth is allowed to call unsafe methods (ex. POST) to the server.
The above setup works fine only if the CSRF token remains the same until the browsing session ends.
Question: Does Django's CSRF token get updated during the course of a browsing session? If 'yes', does that mean I would need to apply the ensure_csrf_cookie() decorator to all the views I have?
1) Does Django's CSRF token get updated during the course of a browsing session?
Looks like the CSRF token is unique per session, but it is based in my observations, I have no "official" source. With Angular.js I use the following code without problems:
angular.module('app', ...)
.config(function($httpProvider) {
var cookies = document.cookie.split(';');
var csrftoken = _.find(cookies, function(v) {
return v.trim().indexOf('csrftoken=') == 0;
});
if(csrftoken) {
$httpProvider.defaults.headers.common['X-CSRFToken'] = csrftoken.split('=')[1];
}
})
Since I serve the HTML from Django, by the time Angular bootstraps the cookie is already there.
2) If 'yes', does that mean I would need to apply the ensure_csrf_cookie() decorator to all the views I have?
You can try CORS instead if CSRF. Otto Yiu maintains the django-cors-headers package, which is known to work correctly with REST framework APIs.
Some (untested) ideas to apply ensure_csrf_cookie():
monkey-patch APIView
create a CSRFCookie mixin and add it to your views
apply ensure_csrf_cookie() to your base classes
Giving support to the #Paulo Scardine ideas of applying the ensure_csrf_cookie() (which I consider valid, and useful), I would like to add a new one possible solution to it, if you definitely have to ensure_csrf_cookie() in all your views. You could write a custom middleware, and implement the logic that is there inside the ensure_csrf_cookie. Something like this:
On your app.middleware.py:
from django.middleware.csrf import get_token
class EnsureCsrfCookie(object):
def process_request(self, request):
# Forces process_response to send the cookie
get_token(request)
and of courses on your settings file add the middleware to the MIDDLEWARE_CLASSES:
MIDDLEWARE_CLASSES = (
.,
.,
.,
'app.middleware.EnsureCsrfCookie',
.,
.,
.,
)
It is just one idea more to face this problem. I hope it can be useful for somebody in the future.
I'm trying to get my MVC3 site to redirect from HTTPS back to HTTP when the user browses to a page where it's not required (and they aren't logged in). I Don't want to have the load of running the whole site HTTPS but it's looking like thats the way I'll have to go.
I've been having loads of trouble with remote debug and symbols, but having gone back in time to 1985 and using message box equivalents to debug with I've come to the following conclusion:
if (filterContext.ActionDescriptor
.GetCustomAttributes(typeof(RequireHttpsAttribute), true)
.Any()
)
{
return true;
}
return false;
Always returns false.
The controller def starts as:
[FilterIP(
ConfigurationKeyAllowedSingleIPs = "AllowedAdminSingleIPs",
ConfigurationKeyAllowedMaskedIPs = "AllowedAdminMaskedIPs",
ConfigurationKeyDeniedSingleIPs = "DeniedAdminSingleIPs",
ConfigurationKeyDeniedMaskedIPs = "DeniedAdminMaskedIPs"
)]
[RequireHttps]
public class AccountController : Controller
{
And it doesn't seem to work for any actions in this controller (although they do get successfully routed to SSL).
Any suggestions? I'd love to see an answer for what I perceive as my own nubery ;)
Custom NotRequreHttpsAttribute tutorial
I use the above link post to implement my custom attribute, and redirect from https to http. Hope this helps.
My problem was discovered to be related to the bindings on the server published to. We use the same server for stage and production, and the stage https bindings were not set, so whenever it was calling an https page it was resolving into our production site (which looked the same so it was hard to spot).
Once I added a binding it was all solved. My code was ok...
I'm working on a web-project which uses GWT on client and Java on server side (tomcat7).
If cookies are enabled on the browser, everything works fine. I can use sessions without any problems.
If cookies are disabled on the browser, sessions doesn't work.
I guess, this his mainly something to do with GWT apps being a single web-page application which only requests data from the server via ajax.
Is there a way to get sessions working under such circumstances?
Help is very appreciated!
All the best,
Thomas
If you using GWT RPC, you will need to modify your RPC urls to burn in the jsessionid as discussed in this forum post. Though I am not sure if line Cookies.getCookie("JSESSIONID") as shown the forum post will work in your case. You might need to parse the location.href
On the server side you can access the session as follows:
public class NameImpl extends RemoteServiceServlet implements NameService {
public void doSomething() throws IllegalArgumentException{
HttpSession hs = this.getThreadLocalRequest().getSession();
//Do whatever it is you want to do with this information.
}
}
Not 100% sure that if is what you are asking for, but it seems like the most reasonable answer.