I have an Next.js app that receives data from another app on the backend and send it to it's on client as cookies. These cookies are working fine on localhost, but they are not being set properly when I deploy the app to AWS Amplify.
I'm using the cookie module and what my backend does is:
// creates an object with the cookie options
const cookiesOptions = {
httpOnly: "true",
maxAge: (60*60)*24,
sameSite: "None",
secure: "true",
path: "/",
};
// creates a cookies array that will store the needed user credetials,
// initializing it with a public cookie (not HttpOnly) that stores the user's nickname
const cookies = [cookie.serialize(`${AUTH_COOKIE.PREFIX}-${AUTH_COOKIE.LOGGED_USER}`, userName, {
maxAge: cookiesOptions.maxAge,
sameSite: cookiesOptions.sameSite,
secure: cookiesOptions.secure,
path: cookiesOptions.path
})];
// generates a name for the cookie of each user's credential and add this cookie to the cookies array
Object.keys(userData).forEach(prop => {
const userProp = userData[prop].trim();
if (userProp.length) {
const cookieName = AUTH_COOKIE.PREFIX +
'-' +
prop.slice(0, 2) +
prop.charAt(prop.length-1).toLowerCase();
cookies.push(cookie.serialize(cookieName, userProp, cookiesOptions));
}
});
// sets the cookies to the response header
res.setHeader("Set-Cookie", cookies);
// redirects the user to the home page
res.status(302).redirect("/");
The thing is that only the first cookie (nickname) is being set. The ones that I generate in the Object.keys(userData).forEach loop are not. I tried to set each cookie manualy as with the nickname one, but it still doesn't work. I've checked and I'm sure that they are being generated, they just don't go with he response to the client.
Also, this is the exact same code that I used for previous deployed apps and it works just fine, all the cookies are set properly. But now, with this one, it just doesn't work.
I'm seeing some odd behavior with a cookie on the server side, and would like to understand why.
On the client:
document.cookie = 'test_cookie=' + '[AB]cd|ef-gh[IJ]' + '; path=/;';
document.cookie = 'test_cookie2=' + 'cd|ef-gh' + '; path=/;';
On the server:
headers = httpServletRequest.getHeaders()
// iterate and print headers
cookies = httpServletRequest.getCookies();
// iterate and print headers
Output:
// Both are there on the header, so tomcat doesn't block it:
...
header: cookie: test_cookie=[AB]cd|ef-gh[IJ]; test_cookie2=cd|ef-gh
// Only one shows up from getCookies()
...
cookie: test_cookie2=cd|ef-gh
// no test_cookie ???
Why am I not able to see the test_cookie2?
I could uri-encode before I set it on the client, but I thought '[' and ']' were allowed cookie characters?
Is there a more correct way to set it?
Here's the way to set the cookie correctly on the frontend:
document.cookie = 'test_cookie="[AB]cd|ef-gh[IJ]"; path=/';
Not the double quotes around the cookie value that contains the special characters.
I'm writing a flex application that polls an xml file on the server to check for updated data every few seconds, and I'm having trouble preventing it from caching the data and failing to respond to it being updated.
I've attempted to set headers using the IIS control panel to use the following, without any luck:
CacheControl: no-cache
Pragma: no-cache
I've also attempted adding a random HTTP GET parameter to the end of the request URL, but that seems like it's stripped off by the HttpService class before the request is made. Here's the code to implement it:
http.url = "test.xml?time=" + new Date().getMilliseconds();
And here's the debug log that makes me think it failed:
(mx.messaging.messages::HTTPRequestMessage)#0
body = (Object)#1
clientId = (null)
contentType = "application/x-www-form-urlencoded"
destination = "DefaultHTTP"
headers = (Object)#2
httpHeaders = (Object)#3
messageId = "AAB04A17-8CB3-4175-7976-36C347B558BE"
method = "GET"
recordHeaders = false
timestamp = 0
timeToLive = 0
url = "test.xml"
Has anyone dealt with this problem?
The cache control HTTP header is "Cache-Control" ... note the hyphen! It should do the trick. If you leave out the hyphen, it is not likely to work.
I used the getTime() to make the date into a numeric string that did the trick. I also changed GET to POST. There were some issues with different file extensions being cached differently. For instance, a standard dynamic extension like .php or .jsp might not be cached by the browser and
private var myDate:Date = new Date();
[Bindable]
private var fileURLString:String = "http://www.mysite.com/data.txt?" + myDate.getTime();
Hopefully this helps someone.
I also threw a ton of the header parameters at it but they never fully did the trick. Examples:
// HTTPService called service
service.headers["Pragma"] = "no-cache"; // no caching of the file
service.headers["Cache-Control"] = "no-cache";
Bug:
I've got an ASP.NET web application that occasionally sets identical cookie keys for ".www.mydomain.com" and "www.mydomain.com". I'm trying to figure out what default cookie domain ASP.NET sets, and how I accidentally coded the site to sometimes prepend a "." to the cookie domain.
When 2 cookies have the same key and are sent up from the browser, the ASP.NET web application is unable to differentiate between the two because the domain value is not sent in the header. (See my previous question)
Evidence:
I've enabled W3C logging on the web server and verified that both cookies are sent from the client. Here's an example from the log file (paired down for brevity).
80 GET /default.aspx page= 200 0 0 - - - - - +MyCookie2=sessionID=559ddb9b-0f38-4878-bb07-834c2ca9caae;+MyCookie2=sessionID=e13d83cd-eac2-46fc-b39d-01826b91cb2c;
Possible Factor:
I am using subdomain enabled forms authentication.
Here's my web.config settings:
<authentication mode="Forms">
<forms domain="mydomain.com" enableCrossAppRedirects="true" loginUrl="/login" requireSSL="false" timeout="5259600" />
</authentication>
Here's and example of setting custom cookies:
HttpCookie cookie1 = new HttpCookie("MyCookie1") {HttpOnly = true, Expires = expiration};
logosCookie["email"] = user.Email;
logosCookie["keycode"] = user.PasswordHash;
logosCookie["version"] = currentCookieVersion;
context.Response.Cookies.Remove("cookie1");
context.Response.Cookies.Add(cookie1);
// set FormsAuth cookie manually so we can add the UserId to the ticket UserData
var userData = "UserId=" + user.UserID;
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, user.Email, now, expiration, true, userData);
string str = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, str)
{
HttpOnly = true,
Path = FormsAuthentication.FormsCookiePath,
Secure = FormsAuthentication.RequireSSL,
Expires = ticket.Expiration
};
if (FormsAuthentication.CookieDomain != null)
{
cookie.Domain = FormsAuthentication.CookieDomain;
}
context.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
context.Response.Cookies.Add(cookie1 );
Here's another example of setting a cookie.
var cookie2 = new HttpCookie("MyCookie2");
cookie2[CookieSessionIdKey] = Guid.NewGuid();
cookie2.Expires = DateTime.Now.AddYears(10);
HttpContext.Current.Response.Cookies.Set(cookie2);
Undesirable Resolution:
I can manually force the cookie domain to be a specific value, but I'd like to avoid explicitly declaring the domain. I'd prefer to use the default framework behavior and change my use of ASP.NET to avoid prepend the "." to the cookie domain for custom cookies.
When no domain is explicitly set by the server on the response, the browser is free to assign the cookie domain value. I haven't figured out exactly what conditions result in the browser setting "www.mydomain.com" vs ".mydomain.com" on a cookie domain when no domain is provided on the response, but it happened.
I have a feeling it's a result of explicitly setting the .ASPAUTH cookie domain value to ".mydomain.com" to enable cross subdomain authentication, while leaving other custom cookie domains set to the default (empty string, or "").
I'm going to go with the undesired solution, and explicitly set the cookie domain for all custom cookies to avoid browser quirks.
How can I detect on the server (server-side) whether cookies in the browser are disabled? Is it possible?
Detailed explanation: I am processing an HTTP request on the server. I want to set a cookie via the Set-Cookie header. I need to know at that time whether the cookie will be set by the client browser or my request to set the cookie will be ignored.
Send a redirect response with the cookie set; when processing the (special) redirected URL test for the cookie - if it's there redirect to normal processing, otherwise redirect to an error state.
Note that this can only tell you the browser permitted the cookie to be set, but not for how long. My FF allows me to force all cookies to "session" mode, unless the site is specifically added to an exception list - such cookies will be discarded when FF shuts down regardless of the server specified expiry. And this is the mode I run FF in always.
You can use Javascript to accomplish that
Library:
function createCookie(name, value, days) {
var expires;
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString();
}
else expires = "";
document.cookie = name + "=" + value + expires + "; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
function eraseCookie(name) {
createCookie(name, "", -1);
}
function areCookiesEnabled() {
var r = false;
createCookie("testing", "Hello", 1);
if (readCookie("testing") != null) {
r = true;
eraseCookie("testing");
}
return r;
}
Code to run:
alert(areCookiesEnabled());
Remember
This only works if Javascript is enabled!
I dont think there are direct ways to check. The best way is to store a value in the cookie and try to read them and decide whether cookies are enabled or not.
The below answer was written a long time ago. Now, for better or worse, due to laws in various countries it has become either good practice - or a legal requirement - not to require cookies except where necessary, at least until the user has had a chance to consent to such mechanisms.
It's a good idea to only do this when the user is trying to do something that initiates a session, such as logging in, or adding something to their cart. Otherwise, depending on how you handle it, you're potentially blocking access to your entire site for users - or bots - that don't support cookies.
First, the server checks the login data as normal - if the login data is wrong the user receives that feedback as normal. If it's right, then the server immediately responds with a cookie and a redirect to a page which is designed to check for that cookie - which may just be the same URL but with some flag added to the query string. If that second page doesn't receive the cookie, then the user receives a message stating that they cannot log in because cookies are disabled on their browser.
If you're following the Post-Redirect-Get pattern for your login form already, then this setting and checking of the cookie does not add any additional requests - the cookie can be set during the existing redirect, and checked by the destination that loads after the redirect.
Now for why I only do a cookie test after a user-initiated action other than on every page load. I have seen sites implement a cookie test on every single page, not realising that this is going to have effects on things like search engines trying to crawl the site. That is, if a user has cookies enabled, then the test cookie is set once, so they only have to endure a redirect on the first page they request and from then on there are no redirects. However, for any browser or other user-agent, like a search engine, that doesn't return cookies, every single page could simply result in a redirect.
Another method of checking for cookie support is with Javascript - this way, no redirect is necessarily needed - you can write a cookie and read it back virtually immediately to see if it was stored and then retrieved. The downside to this is it runs in script on the client side - ie if you still want the message about whether cookies are supported to get back to the server, then you still have to organise that - such as with an Ajax call.
For my own application, I implement some protection for 'Login CSRF' attacks, a variant of CSRF attacks, by setting a cookie containing a random token on the login screen before the user logs in, and checking that token when the user submits their login details. Read more about Login CSRF from Google. A side effect of this is that the moment they do log in, I can check for the existence of that cookie - an extra redirect is not necessary.
Try to store something into a cookie, and then read it. If you don't get what you expect, then cookies are probably disabled.
I always used this:
navigator.cookieEnabled
According to w3schools "The cookieEnabled property is supported in all major browsers.".
However, this works for me when i am using forms, where i can instruct the browser to send the additional information.
check this code , it' will help you .
<?php
session_start();
function visitor_is_enable_cookie() {
$cn = 'cookie_is_enabled';
if (isset($_COOKIE[$cn]))
return true;
elseif (isset($_SESSION[$cn]) && $_SESSION[$cn] === false)
return false;
// saving cookie ... and after it we have to redirect to get this
setcookie($cn, '1');
// redirect to get the cookie
if(!isset($_GET['nocookie']))
header("location: ".$_SERVER['REQUEST_URI'].'?nocookie') ;
// cookie isn't availble
$_SESSION[$cn] = false;
return false;
}
var_dump(visitor_is_enable_cookie());
NodeJS - Server Side - Cookie Check Redirect
Middleware - Express Session/Cookie Parser
Dependencies
var express = require('express'),
cookieParser = require('cookie-parser'),
expressSession = require('express-session')
Middleware
return (req, res, next) => {
if(req.query.cookie && req.cookies.cookies_enabled)
return res.redirect('https://yourdomain.io' + req.path)
if(typeof(req.cookies.cookies_enabled) === 'undefined' && typeof(req.query.cookie) === 'undefined') {
return res.cookie('cookies_enabled', true, {
path: '/',
domain: '.yourdomain.io',
maxAge: 900000,
httpOnly: true,
secure: process.env.NODE_ENV ? true : false
}).redirect(req.url + '?cookie=1')
}
if(typeof(req.cookies.cookies_enabled) === 'undefined') {
var target_page = 'https://yourdomain.io' + (req.url ? req.url : '')
res.send('You must enable cookies to view this site.<br/>Once enabled, click here.')
res.end()
return
}
next()
}
The question whether cookies are "enabled" is too boolean. My browser (Opera) has a per-site cookie setting. Furthermore, that setting is not yes/no. The most useful form is in fact "session-only", ignoring the servers' expiry date. If you test it directly after setting, it will be there. Tomorrow, it won't.
Also, since it's a setting you can change, even testing whether cookies do remain only tells you about the setting when you tested. I might have decided to accept that one cookie, manually. If I keep being spammed, I can (and at times, will) just turn off cookies for that site.
If you only want to check if session cookies (cookies that exist for the lifetime of the session) are enabled, set your session mode to AutoDetect in your web.config file, then the Asp.Net framework will write a cookie to the client browser called AspxAutoDetectCookieSupport. You can then look for this cookie in the Request.Cookies collection to check if session cookies are enabled on the client.
E.g. in your web.config file set:
<sessionState cookieless="AutoDetect" />
Then check if cookies are enabled on the client with:
if (Request.Cookies["AspxAutoDetectCookieSupport"] != null) { ... }
Sidenote: By default this is set to UseDeviceProfile, which will attempt to write cookies to the client so long as the client supports them, even if cookies are disabled. I find it slightly odd that this is the default option as it seems sort of pointless - sessions won't work with cookies disabled in the client browser with it set to UseDeviceProfile, and if you support cookieless mode for clients that don't support cookies, then why not use AutoDetect and support cookieless mode for clients that have them disabled...
I'm using a much more simplified version of "balexandre"'s answer above. It tries to set, and read a session cookie for the sole purpose of determining if cookies are enabled. And yes, this requires that JavaScript is enabled as well. So you may want a tag in there if you care to have one.
<script>
// Cookie detection
document.cookie = "testing=cookies_enabled; path=/";
if(document.cookie.indexOf("testing=cookies_enabled") < 0)
{
// however you want to handle if cookies are disabled
alert("Cookies disabled");
}
</script>
<noscript>
<!-- However you like handling your no JavaScript message -->
<h1>This site requires JavaScript.</h1>
</noscript>
The cookieEnabled property returns a Boolean value that specifies whether or not cookies are enabled in the browser
<script>
if (navigator.cookieEnabled) {
// Cookies are enabled
}
else {
// Cookies are disabled
}
</script>
<?php session_start();
if(SID!=null){
echo "Please enable cookie";
}
?>
Use navigator.CookieEnabled for cookies enabled(it will return true of false) and the Html tag noscript. By the way navigator.cookieEnabled is javascript so don't type it in as HTML