I recently migrated an app from CF2010 to CF2018 and we're having problems on sessions when a user logs in.
Adding some dumps and aborts I see that the session is successfully set on a valid login, but when using cflocation or cfheader it loses the session (application.cfc reruns onSessionStart). My application.cfc looks like:
this.applicationTimeout = createTimeSpan(0,8,0,0);
this.sessionmanagement = true;
this.clientmanagement = false;
this.sessiontimeout = createTimeSpan(0,0,20,0);
this.scriptProtect = "all";
this.setClientCookies = true;
this.showDebugOutput = false;
this.enablecfoutputonly = false;
onSessionStart is pretty simple:
public void function onSessionStart() {
lock scope="session" type="exclusive" timeout="10" {
session.started = now();
session.loggedIn = false;
};
lock scope="application" type="exclusive" timeout="5" {
application.sessions = application.sessions + 1;
};
writeLog(file = "g-session-log", type = "information", application = "no", text = "session started:");
};
I can see the log file gain an entry when the login page is processed. In the server admin I have "Use J2EE session variables" and "Enable Session Variables" both checked. Cookie timeout is 1440, HTTPOnly is checked and "Disable updating ColdFusion internal cookies using ColdFusion tags/functions" is checked.
Found the issue - answering in case anyone else has this problem. In my onApplicationStart() I set an http and https siteroot. On <cflocation> called application.secureSiteRoot but because I was moving the SSL cert over for testing I had it set to http, not https. That prevented the cookies from being set.
Related
I am doing a project where I load a webview in my application(using visual studio 2012). On before loading web view i send a curl request to get some access_token which i need to set in the cookie for that particular webview so that the user is signed in for that webview automatically. So in the callback from curl when i get the token i call setCookie on cef global cookie Manager but it always returns me false.
CefRefPtr<CefCookieManager> cookieManager=CefCookieManager::GetGlobalManager();
CefString cefURL ;
cefURL.FromString(url.GetUTF8String());
bool retVal = cookieManager->SetCookie(cefURL,cookie);
Am i doing something wrong, is it because i am doing it on the curl callback which is a seperate thread.
CefRefPtr<CefCookieManager> manager =
CefCookieManager::GetGlobalManager(nullptr);
DCHECK(manager.get());
CefCookie cookie;
CefString(&cookie.name).FromString(key);
CefString(&cookie.value).FromString(value);
CefString(&cookie.domain).FromString(domain);
CefString(&cookie.path).FromString("/");
cookie.has_expires = true;
cookie.expires.year = 2099;
cookie.expires.month = 1;
cookie.expires.day_of_week = 1;
cookie.expires.day_of_month = 1;
std::string url = "https://" + domain;//eg:".stackoverflow.com"
//manager->SetCookie(url, cookie, nullptr);
CefPostTask(TID_IO, NewCefRunnableMethod(manager.get()
, &CefCookieManager::SetCookie
, CefString(url.c_str()), cookie, nullptr));
Set up through interprocess communication,use CefPostTask function
My user comes from a 3rd party site via http post with login credentials encrypted in the URL.
Once the index.cfm recognizes these variables, it sends the request to:
<cflocation url="login.cfm?vals=#URLEncodedFormat(url.vals)#" addtoken="yes">
The login.cfm builds a session struct if the login credentials are valid.
Session.user.userID = 1;
Session.user.firstName = "jo";
Session.user.lastName = "boo";
Then, it does:
<cflocation url="somepage.cfm" addtoken="yes">
When I dump the session variable in somepage.cfm, I do not see the session.user struct. Also, I keep seeing different cfid, cftoken on somepage.cfm every single I refresh. I am on ColdFusion 10.
Any ideas? How can I keep the session.user?
Edit: application.cfc has
this.name = "My Application";
this.applicationTimeout = createTimeSpan(0,2,0,0);
this.clientManagement = true;
this.loginStorage = "session";
this.sessionManagement = true;
this.sessionTimeout = createTimeSpan(0,0,30,0);
this.setClientCookies = true;
this.setDomainCookies = false;
this.scriptProtect = "all";
this.javaSettings = {LoadPaths = ["#GetDirectoryFromPath(GetCurrentTemplatePath())#java/"], reloadOnChange=true, watchInterval=180};
EDIT: here are the files
http://1drv.ms/1kjnQO2
Unzip them to your C:\ColdFusion10\cfusion\wwwroot\
then go to :
http://localhost:8500/test/call.cfm
EDIT: 19:00 - 10Jun:
Wow, this really sucked! Came home, downloaded the zip, opened it up to localhost. When I run, I can see the session.user variables from call.cfm.
<cfdump var="#server#">
gives me:
coldfusion
struct
InstallKit Native Windows
appserver J2EE
expiration {ts '2012-10-30 10:35:35'}
productlevel Developer
productname ColdFusion Server
productversion 10,0,0,283111
rootdir C:\ColdFusion10\cfusion
I am not sure if this has something to do with the CF server version.
UPDATE: 09:00 11-Jun.
Once I disable "Use J2EE session variables " in CFAdmin, the session variables are visible to call.cfm. Now, I have to make it work with J2EE session variables when they are enabled.
I want to login with gmail/google account and I found this tutorial Gmail Login in Coldfusion. I done All the steps and After login my page redirect then I want to display user Profile information so I dump this
<cfdump var="#session.profilesArray#">
but it gives me an empty array.why I am not getting my profile data after successfully lo-gin.
If I am getting wrong way for fetching my profile then what is correct way. Thanks.
You just add this line into your scope
Open your Application.cfc and then add this code
change scope = "https://www.googleapis.com/auth/analytics.readonly" with scope = "https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile
you can just add scope = "https://www.googleapis.com/auth/userinfo.profile but if u want to access email then add second one as I Post in my answer.
<cfset request.oauthSettings =
{scope = "https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile",
client_id = "Your-id",
client_secret = "your-secret",
redirect_uri = "redirect-page",
state = "optional"} />
Now you can get User Information from function that you can call like this
<cfscript>
public function getProfile(accesstoken) {
var h = new com.adobe.coldfusion.http();
h.setURL("https://www.googleapis.com/oauth2/v1/userinfo");
h.setMethod("get");
h.addParam(type="header",name="Authorization",value="OAuth #accesstoken#");
h.addParam(type="header",name="GData-Version",value="3");
h.setResolveURL(true);
var result = h.send().getPrefix();
return deserializeJSON(result.filecontent.toString());
}
</cfscript>
<cfoutput>
<cfset show = getProfile(session.ga_accessToken)>
<cfdump var="#show#">
</cfoutput>
Hope this will help you.
I need to copy files from one folder to the another on the same sftp server. My code currently copies the files locally and reuploads them.
<cfftp
action = "open"
username = "#APPLICATION.intxml.SFTPUSERNAME#"
password = "#APPLICATION.intxml.SFTPPASSWORD#"
connection = "sftpcon"
server = "#APPLICATION.intxml.SFTPADDRESS#"
port = "#APPLICATION.intxml.SFTPPORT#"
timeout = "#APPLICATION.pageTimeout#"
secure = "#sftp#"/>
<cfif cfftp.succeeded>
<cfftp action = "LISTDIR" stopOnError = "No" name = "ListFiles" directory = "/#sfolder#" connection = "sftpcon"/>
<cfloop query=getFiles>
<cfftp action = "GETFILE"
stopOnError = "Yes"
name = "theFile"
transferMode = "binary"
timeout = 3600
retrycount = 10
remoteFile = "#sfolder##name#"
localFile = "#dfolder#/#name#"
failIfExists = "no"
connection = "sftpcon">
<cfftp action = "PUTFILE"
stopOnError = "Yes"
name = "theFile"
transferMode = "binary"
timeout = 3600
retrycount = 10
localfile = "#sfolder##name#"
remoteFile = "#dfolder#/#name#"
failIfExists = "no"
connection = "sftpcon">
</cfloop>
</cfif>
<cfftp action = "close"
connection = "sftpcon"
stopOnError = "Yes">
Is there a better way to do this with coldfusion?
With CFFTP you can do a RENAME (check the docs) which should solve your problem
Found out that the ftp protocol does not provide a way to remotely copy a file into another folder and keep the original. That precludes coldfusion from providing a solution. Moving files on the other hand can be done with a rename. See the other answer and comments on the original question.
Code to show directories of files:
<cfftp
username= "username"
password= "password"
port= "22"
server= "hostofyousystem"
secure= "yes"
name= "ftpconnection"
action= "listdir"
directory= "/" />
<cfdump var="#ftpconnection#" />
<cfoutput query="ftpconnection">
#path#<br/>
</cfoutput>
Code to get file and save it in our system if file exist then replace:
<cfftp
username= "username"
password= "password"
port= "22"
server= "hostofyousystem"
secure= "yes"
action= "getFile"
remotefile= "/myfile.csv"
localfile= "D:/web/files/Data/thisfile.csv"
failIfExists="no" />
I have 2 subdomains and I need to set and read the same cookie from both websites.
When I use localhost, everything works fine.
When I switch to using valid urls, the cookie infomation is not really being updated when I update it (expire date on logout).
I have the domain of the cookie set to ".mysite.com"
what is wrong?
The answer was to set the domain to the cookie when expiring it on logout
HttpCookie aCookie = Request.Cookies["Token"];
aCookie.Expires = DateTime.Now.AddDays(-1);
aCookie.Domain = ConfigurationManager.AppSettings["CookieDomain"];
Response.Cookies.Add(aCookie);
Try this:
if (Request.Cookies["Token"] != null) {
HttpCookie aCookie = Request.Cookies["Token"];
aCookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies["Token"] = aCookie;
}
Instead of adding it, set it to the existing cookie.
Your forms authentication setting in the web.config needs to enable cross app redirects:
<authentication mode="Forms">
<forms loginUrl="~/login.aspx" protection="All" timeout="960" name=".ASPXAUTH" path="/" requireSSL="false" slidingExpiration="false" defaultUrl="~/default.aspx" enableCrossAppRedirects="true"/>
</authentication>
Here is my code: (works fine on localhost but not subdomain, never logs the user out because the cookie doesnt get expired)
Login page:
FormsAuthentication.SetAuthCookie(UserName.Text, true);
// set the active collab cookie
Member member = MemberManager.GetMemberByUsername(UserName.Text);
HttpCookie cookie = new HttpCookie("Token", member.Profile.Token);
cookie.Domain = ConfigurationManager.AppSettings["CookieDomain"];
cookie.Expires = DateTime.Now.AddYears(1);
Response.Cookies.Add(cookie);
Globax ASAX
if (HttpContext.Current.Request.Cookies["Token"] != null) {
string token = HttpContext.Current.Request.Cookies["Token"].Value;
if (!string.IsNullOrEmpty(token)) {
// If the user is logged in with a different token
// or not logged in at all
// then log them in with the token from the cookie
if ((MemberManager.CurrentMember != null && MemberManager.CurrentMember.Profile.Token != token) || User == null) {
Member member = MemberManager.GetMemberByToken(token);
if (member != null) {
FormsAuthentication.SetAuthCookie(member.User.UserName, true);
}
}
}
}
Logout Code:
if (Request.Cookies["Token"] != null) {
HttpCookie aCookie = Request.Cookies["Token"];
aCookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(aCookie);
}
Web.Config
<machineKey
validationKey="{-snip-}"
decryptionKey="{-snip-}"
validation="SHA1"
decryption="AES" />
<authentication mode="Forms">
<forms name="AuthCookie"
path="/"
loginUrl="~/login.aspx"
protection="All"
timeout="60">
</forms>
</authentication>