I'm creating cookies in VertX and want to remove them again once a users logs out.
AccountController.handleLogin(vertx, router.post("/login"))
...
fun handleLogin(vertx: Vertx, route: Route) {
route.handler { rtx ->
rtx.request().bodyHandler { btx ->
vertx.executeBlocking<Login>({
it.complete(AccountController.login(Json.decodeValue(String(btx.bytes), Login::class.java)))
}, {
if (it.succeeded()) {
// set some cookies
rtx.addCookie(Cookie.cookie("atom-session", it.result().session).setHttpOnly(true).setSecure(secure))
That cookie can now be seen in Chrome:
When I want to remove that cookie again:
AccountController.handleLogout(vertx, router.post("/logout"))
...
fun handleLogout(vertx: Vertx, route: Route) {
route.handler { rtx ->
rtx.request().bodyHandler { btx ->
vertx.executeBlocking<Logout>({
val logout = Json.decodeValue(String(btx.bytes), Logout::class.java)
it.complete(AccountController.logout(logout))
}, {
if (it.succeeded()) {
log.info("Cookies Will No Be Removed ...")
rtx.removeCookie("atom-session")
log.info("DONE!")
I can see the messages being printed saying that cookies will be removed, but when I refresh the resources in Chrome, all the cookies that were set on login are still there. including atom-session
Am I doing this wrong or is this a bug in VertX ?
The removeCookie method will remove it from the request object but that does not remove a cookie from a web client. In order to force it to be removed from a client the cookie must be sent back with an expiration date. For example you should do:
rtx.getCookie("atom-session").setMaxAge(0)
This is not a vert.x feature per se, but how cookies work.
Related
Like to ask a CORS cookie question again, I have spent quite some time on this but cannot resolve it.
Here is the situation.
I got a Backend api in nodejs(http://localhost:5000), and a React Frontend app(http://localhost:3000).
In Backend side, Cors setting is like this.
private initializeCors(){
this.app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Headers", "Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", "true");
next();
});
}
I have set { credentials: "include" } in Fetch Api when login with username/password.
Set-Cookie has been set in response and I can see it saved in browser.
Cookie is with the format "Authorize=TOKEN;HttpOnly;Max-Age=3600;"
Cookie in browser
Then when route to another url and it cannot retrieve data from Backend with 401 exception.
Here is the code of the sequence call.
const credentialsInclude : "include" | "omit" | "same-origin" | undefined = "include";
function getAllPayments() {
const requestOptions = {
method: 'GET',
credentials: credentialsInclude
};
return fetch(apiUrls.GET_ALL_PAYMENTS, requestOptions).then(handleResponse);
}
I can see the cookie not added into header.
No cookie in header
I have followed the best answer of here, but cannot get it work.
Any suggestions? Thanks.
I have just figured out. The issue was not caused by the CORS settings. It caused by the Cookie itself.
For my case, I need to add Path=/; into Set-Cookie in response headers. So that the cookie from response could be added to sequenced requests after successful login.
I am using sessions to manage application state in ASP.NET CORE and it's configured as below.
services.AddSession(options =>
{
options.CookieName = ".my.Session";
options.IdleTimeout = TimeSpan.FromSeconds(20);
});
It's working on localhost but on remote IIS 8 it's not creating cookies so not able to get the values. I also have enabled CORS and don't know what exactly caused this problem. In log it's not showing error either.
In response header set cookie is present but not set in browser
I had this problem some time ago. It may be related with the new Cookie Policy.
Try to set options.CheckConsentNeeded = context => false;. So inside "ConfigureServices" in Startup.cs it need to be like this:
public void ConfigureServices(IServiceCollection services)
{
var connection = Configuration["ConnectionStrings:DefaultConnection"];
services.AddDbContext<ProjectDbContext>(options => options.UseMySql(connection, b => b.MigrationsAssembly("PrimaryProject")));
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
//Here comes the change:
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(connection));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddSessionStateTempDataProvider();
services.AddSession();
}
Regards,
H. Eberhardt
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(20);
options.CookieHttpOnly = true;
});
May be it's working, Try it now
I'm doing a BrowserClient POST across domains and don't see my cookies being included.
This the response I'm getting:
When I send another POST request, I don't see the cookies being included:
Going straight to the test page, I can see the cookies being included:
The Dart code I use to make a POST:
var client = new BrowserClient();
client.post(url, body: request, headers:{"Content-Type" : "application/json", "Access-Control-Allow-Credentials":"true"}).then((res) {
if (res.statusCode == 200) {
var response = JSON.decode(res.body);
callback(response);
} else {
print(res.body);
print(res.reasonPhrase);
}
}).whenComplete(() {
client.close();
});
Not sure about the Access-Control-Allow-Credentials header I'm including, with or without it, nothing changes.
Am I missing headers on the server side that needs to be set on the response or is Dartium blocking cross-domain cookies?
More details on Information Security and the reasoning behind setting cookies via the server.
Update: Enhancement request logged: https://code.google.com/p/dart/issues/detail?id=23088
Update: Enhancement implemented, one should now be able to do var client = new BrowserClient()..withCredentials=true; based on
https://github.com/dart-lang/http/commit/9d76e5e3c08e526b12d545517860c092e089a313
For cookies being sent to CORS requests, you need to set withCredentials = true. The browser client in the http package doesn't support this argument. You can use the HttpRequest from dart:html instead.
See How to use dart-protobuf for an example.
Currently, I have an HTML page that sends a POST request to a Python server with login details. The Python server verifies the login and then sends back a cookie via headers (I'm using the Cookie class built into the Python library). I want to redirect as soon as I get a 200 OK status. The issue is that the cookies are not being set quickly enough, so the redirect happens before the cookies are set and thus the check_login page will display that I have not logged in.
I want the browser to store an HTTPOnly cookie. Is there something in the XMLHttpRequest API that will let me redirect after the cookie has been stored, or an alternative method?
Thanks!
The HTTPRequest code:
var httpRequest = new XMLHttpRequest();
var url = 'http://localhost/login/';
httpRequest.onreadystatechange = function(){
if (httpRequest.readyState == 4) {
if(httpRequest.status == 200) {
window.location = "http://localhost/check_login/";
}
};
httpRequest.open("POST", url,false);
httpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
httpRequest.send(/*login details*/);
This request is called by clicking a button. If I go back to the page that this button is on and then click it again, I will always be logged in because the cookie was already set from the first click.
I am trying to Post and get a cookie. I am a newbie and this is a learning project for me. My impression is that if you use 'set-cookie' one should be able to see an additional 'set-cookie' in the .toSource. (I am trying to accomplish this on Google Apps Site if that makes a difference.) Am I missing something? Here is my code:
function setGetCookies() {
var payload = {'set-cookie' : 'test'};
var opt2 = {'headers':payload, "method":"post"};
UrlFetchApp.fetch("https://sites.google.com/a/example.com/blacksmith", opt2);
var response = UrlFetchApp.fetch("https://sites.google.com/a/example.com/blacksmith")
var openId = response.getAllHeaders().toSource();
Logger.log(openId)
var AllHeaders = response.getAllHeaders();
for (var prop in AllHeaders) {
if (prop.toLowerCase() == "set-cookie") {
// if there's only one cookie, convert it into an array:
var myArray = [];
if ( Array.isArray(AllHeaders[prop]) ) {
myArray=AllHeaders[prop];
} else {
myArray[0]=AllHeaders[prop];
}
// now process the cookies
myArray.forEach(function(cookie) {
Logger.log(cookie);
});
break;
}
}
}
Thanks in advance! I referenced this to develop the code: Cookie handling in Google Apps Script - How to send cookies in header?
Open to any advice.
When you aren't logged in Google Sites won't set any cookies in the response. UrlFetchApp doesn't pass along your Google cookies, so it will behave as if you are logged out.
First the cookie you want to send whose name is 'test' does not have a value. You should send 'test=somevalue'.
Second I am wondering if you are trying to send the cookie to the googlesite server and ask it to reply with the same cookie you previously sent... ?
I am thinking you are trying to act as a HTTP server beside you are a HTTP client.
As a HTTP client your role is only to send back any cookies that the HTTP server have previously sent to you (respecting the domain, expiration... params).