I am making a user signup app for an ecomerce site, but I have run into a very odd problem. When I run this code:
<cfif isValid("email", form.email)>
<cfquery name="check_user" datasource="#request.dsn#">
SELECT var_username, var_password
FROM tbl_users
WHERE var_username = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.EMAIL#">
AND var_password = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.PASSWORD#">
</cfquery>
<cfif check_user.recordcount LT 1>
<cfquery datasource="#request.dsn#" name="insertuser">
INSERT INTO tbl_users (var_username, var_password)
VALUES
(<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.EMAIL#">,
<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.PASSWORD#">)
</cfquery>
<cflogin idletimeout="1800">
<cfloginuser
name = "#FORM.email#"
password ="#FORM.password#"
roles = "0">
</cflogin>
<cflocation addtoken="No" url="#request.secure_url#checkout.cfm">
<cfelse>
<cfset client.error_message = "Your Email Address is already registered.">
<cflocation addtoken="No" url="#request.site_url#New-Account.html">
</cfif>
<cfelse>
<cfset client.error_message = "Your Email Address is not Valid.">
<cflocation addtoken="No" url="#request.site_url#New-Account.html">
</cfif>
What this code is supposed to do, is check to see if the email is already in the database, if its not, it then adds the email/password into the database then logs them in and moves them to the secure checkout site.
What the code is actually doing, is quite different though. It is checking to see if they are in the database, and then adding them, however, after it adds them to the database it skips the login and the cflocation and goes to the cfelse, going back to the original page "New-Account" and displaying the client.error_message.
How is it possible for the code to run the cfif check_user.recordcount and then part way through it skip to the cfelse?
Things I have done to try and narrow down whats happening-
It is getting pass the check_user statement and adding a user, because I have direct access to the database and after trying to signup a user, I delete it and try again (and notice that when I try to create it, it does create it), so I know its getting past the insertuser cfquery. I have changed the cflocation to redirect to google, but it doesnt, and I also have it show on the page whether or not I am logged in, so I know that it is skipping to the cfelse before the cflogin.
I would suggest commenting out all of your cflocations temporarily and seeing if your behaviour is the same. It could be that your login process doesn't finish before your cflocation starts.
Or, it could be that your page submits to itself correctly the first time, and then the second time hits the else clause.
There is nothing in your code that is obviously wrong to me.
Related
I am trying to write an if statement in Coldfusion 16 to check to see if it can connect to the database or that it exists. If it can connect to the database then show the page otherwise show down for maintenance. How should I just check to make sure the database is up? Any help with this would be greatly appreciated.
<cfquery name="DBUP" datasource="datasource">
SELECT ID
FROM dbo.Entry
</cfquery>
<cfif DBUP>
Show Page
<cfelse>
Show Down For Maintenance
</cfif>
You shouldn't directly put a error message or file in a catch statement. We should check one more condition ie) Error code is 0 or not. Imagine in some time the developer may give wrong query like undefined column or missing syntax etc... In that time also the catch will executed. So as per the requirement we have to check the datasource exists or not. If we want to check all type of issue means we no need of the error code conditions.
<cftry>
<cfset showPage = true>
<cfquery name="DBUP" datasource="datasource">
SELECT ID FROM dbo.Entry
</cfquery>
<cfcatch type="database">
<!--- The error code 0 is mentioned Datasource could not be found/exits. --->
<cfif cfcatch.cause.errorcode eq 0 >
<cfset showPage = false >
<!--- Data source does not exists --->
</cfif>
</cfcatch>
</cftry>
Based on showPage value do you business logic here
....
....
....
You will need to add it in Application.cfc onRequest method probably.
<cftry>
<cfquery name="DBUP" datasource="datasource">
SELECT ID
FROM dbo.Entry
</cfquery>
<cfcatch type="any">
Show DOwn For Maintenance
<!---everything optional below this line--->
<!---can show some custom message--->
<cfinclude template="errorMsg.cfm">
<!---stop the processing further--->
<cfabort>
</cfcatch>
</cftry>
I want to implement lock feature in my app. Once a user selects the Customer in my App, that record should not be available to other users. I have created Lock table that contains User ID and Record ID. So in situation when someone else tries to select the same record I will check the Lock table. If a Record ID exists, in the Lock table, I should check if the user is still logged in. I'm wondering if there is a way to check that in ColdFusion 9?
Here is example of my session variable and function that should update Lock table:
userdata
APPFNAME John
APPJOBTITLE Manager
APPLNAME Miller
APPUSERID G890H32
APPUSER jmiller
<cffunction name="onSessionEnd" returnType="void" output="true">
<cfargument name="SessionScope" type="struct" required="true">
<cfargument name="AppScope" type="struct" required="true">
<cfif StructKeyExists(session,"userdata")>
<cfset currentDate = DateFormat(Now(),'mm/dd/yyyy')>
<cfset currentTime = TimeFormat(Now(),'hh:mm tt')>
<cfquery name="updateLock" datasource="Test">
UPDATE Locked
SET l_active = '0',
l_udt = <cfqueryparam value="#currentDate#" cfsqltype="cf_sql_date" maxlength="10" />,
l_utime = <cfqueryparam value="#currentTime#" cfsqltype="cf_sql_char" maxlength="8" />
WHERE l_userID = <cfqueryparam value="#trim(request.userdata.APPUSERID)#" cfsqltype="cf_sql_char" maxlength="10" />
</cfquery>
</cfif>
</cffunction>
The system that I'm working on doesn't have any temporary table that stores currently logged in users. What would be the other option to check if user is logged in? I saw few posts that are related to cflogin but none of them explained this specific scenario. If anyone can help please let me know.
I suggest adding a query to the onSessionEnd() method of your Application.cfc that updates the lock table to indicate that the user is no longer logged in. Whether this update deletes records or updates a field is up to you.
CFBuilder admin storage
15cdb5dcb6.jpg
Application.cfm
34ed7586e1.jpg
Login.cfm
<cfif not isDefined('FORM.submitButton')>
<cfform name="loginForm" method="post" action="#CGI.SCRIPT_NAME#">
Login:
<cfinput type="text" name="login" required="yes">
Password:
<cfinput type="password" name="password" required="yes">
<br>
<cfinput type="submit" name='submitButton' value="Sign">
<br>
<cfinput type="button" name='registerButton' value="Register">
</cfform>
<cfelse>
<cfquery name='getUser' datasource="dbfortest">
SELECT * FROM usertable WHERE login="#FORM.login#" ;
</cfquery>
<cfif getUser.RecordCount NEQ 0>
<cfif FORM.password eq getUser.password>
<cflock scope="Session" timeout="60" type="exclusive" >
<cfset Session.loggedIn = "yes">
<cfset Session.user = "#FORM.login#">
</cflock>
<cfoutput>#StructKeyList(Session)#</cfoutput>
<cfelse>
Your pass isn't correct.
</cfif>
<cfelse>
There is no user with this name.
</cfif>
</cfif>
part of page when i want to use login including.
<cfif Session.loggedIn eq "no">
<cfinclude template="login.cfm">
</cfif>
<cfif structKeyExists(session, "user")>
<cfoutput>Welcome, #Session.user#.</cfoutput>
</cfif>
<cfoutput>#StructKeyList(Session)#</cfoutput>
Hello everyone, please help me understand these sessions' behavior.
The whole problem consists in attempting to pass variables from one page to another.
So after login i don't see the session.user in session struct.
How can i pass this?
Have already tried different browsers.
#Aquitaine has given you some good information. I just wanted to also point out that another part of your problem is likely that you have set a 10 second life span for your sessions. That's probably not long enough.
In the Application.cfm example that you posted you have this line:
sessiontimeout="#createTimespan(0,0,0,10)#"
The arguments for the CreateTimeSpan function are as follows:
createTimespan(days, hours, minutes, seconds)
As such you are assigning a 10 second lifespan for sessions. Perhaps you meant to set 10 minutes instead of 10 seconds.
To figure out what's going on with the session variables, try putting in some debug code right after your cfset session statements to make sure that they're happening. Maybe <cfdump var="#session#">.
You do not need to cflock your session scope (and have not needed to since CFMX). See Adam Cameron's 2013 post on when to lock scopes
If your debug code runs and you see the session variables, but then they're gone on the next page, that may be an issue with your session storage (which is a different part of cfadmin) or else whatever front-end webserver you're using. Try <cfdump var="#session#"> in onRequestStart in Application.cfc and make sure that JSESSIONID is the same on every request. (or try disabling J2EE session variables in CFADMIN and see if the same problem persists with CFID/CFTOKEN).
If your debug code doesn't run, then you should be seeing one of your error conditions.
For ease-of-reading, be consistent in your casing when refering to scopes, e.g. session not Session. While this kind of thing may not matter functionally, it can get you into trouble with portability when referencing paths or components.
Some other issues:
If you are going to use a boolean value for loggedIn then use a boolean value: true or false or 1 or 0 or (if you must) yes or no but not "yes" which is a string; instead of being able to do if (session.loggedIn) if you will have to do if (session.loggedIn == 'yes') and nobody will be happy.
If this is meant to be working, production site code, at a minimum you need to be using cfqueryparam as you do not ever want to pass unescaped user input directly to a database query.
You might also head over to the CFML slack at cfml.slack.com and ask on #cfml-beginners for some pointers on writing login forms.
I'm looking to use "vanity" URLs to redirect to a login page, with a company logo on it.
The URL would be something like: companyname.domain.com
First, I need to query the requested URL to see if "companyname" exists, then either
serve the custom login page if it exists -OR-
show an error page if it doesn't.
The true destination will actually be something like www.domain.com/folder/. But again, I need to display the "vanity" URL throughout the whole application. Example:
companyname.domain.com/clients/?id=somevariable&...
I know I can probably figure it out by trial and error over some period of time. But being a self-taught CF-er, I thought to gain some advice on the "right way" to go about this task.
This is how I ended up doing what I was looking for. Thanks for all the input.
First I added a DNS A record to the domain.com zone like this: * site-ip-address-here
<cfscript>
siteDomainName = cgi.http_host;
if (ListLen(siteDomainName, '.') gt 2) {
siteDomainName = ListFirst(siteDomainName,'.');
}
</cfscript>
<cfif siteDomainName NEQ "www">
<cfquery name="qUrl" datasource="#dsn#">
SELECT id, pre
FROM table
WHERE pre = <cfqueryparam value="#siteDomainName#" cfsqltype="cf_sql_varchar">
</cfquery>
<cfif qUrl.recordCount GT 0>
<cflocation url="/folder/" addtoken="false">
<cfelse>
<cflocation url="http://www.domain.com/error.cfm" addtoken="false">
</cfif>
</cfif>
If anyone has any comments on how it could've been done better, I'm always looking to learn something new.
I have a coldfusion web site I need to change. Have no idea or experience with this environment (I do know ASP.NET). All I need to do is to write a condition based on the referral value (the URL) of the page, and redirect to another page in some cases.
Can anyone give me an example of the syntax that would perform this?
All of the other examples would work...also if you're looking to redirect based on a referral from an external site, you may want to check CGI.HTTP_REFERER. Check out the CGI scope for several other options.
<cfif reFindNoCase('[myRegex]',cgi.http_referer)>
<cflocation url="my_new_url">
</cfif>
...my example uses a regex search (reFind() or reFindNoCase()) to check the referring URL...but you could also check it as a list with / as a delimiter (using listContainsNoCase()) depending on what you're looking for.
Lets assume your the URL variable you are basing this on is called goOn (http://yoursite.com?goOn=yes) then the following code would work:
<cfif structKeyExists(url, "goOn") AND url.goOn eq "yes">
<cflocation url="the_new_url" addtoken="false">
</cfif>
Nothing will happen after the cflocation.
There is a CGI variable scope in ColdFusion that holds information on the incoming request. Try the following:
<cfif CGI.SCRIPT_NAME EQ 'index.cfm'>
<cflocation url="where you want it to redirect" />
</cfif>
To see what else is available within the CGI scope, check out the following:
http://livedocs.adobe.com/coldfusion/8/htmldocs/Expressions_8.html#2679705
Haven't done coldfusion in a little while but:
<cfif some_condition_based_on_your_url>
<cflocation url="http://where_your_referrals_go">
</cfif>
<!--- continue processing for non-redirects --->
A dynamic version.
<cfif isdefined("somecondition")>
<cfset urlDestination = "someurl">
<cfelseif isdefined("somecondition")>
<cfset urlDestination = "someurl">
.
.
.
<cfelse>
<cfset urlDestination = "someurl">
</cfif>
<cflocation url = urlDestination>