Avatar of kenjpete
kenjpete
 asked on

Trying to Link to a Blog Article from an E-mail

I have a blog that is password-protected. Each month I send out an e-mail newsletter that contains excerpts from articles in the blog. Each excerpt has a link to the blog so the user can read the whole story.

I am trying to link to the individual article in the blog from the e-mail. If the user is not logged in to the blog, I want them to go to the login page and then get directed to their requested blog article, not the blog home page.

Here is the code I use to determine if the user is logged in or not:

<!--- Check login status --->
<cfparam name="Session.Auth.isLoggedIn" default="No">

<cfif Session.Auth.isLoggedIn EQ "No">
<cfif  ListLast(CGI.SCRIPT_NAME, "/") EQ "index.cfm">
          <script>
               self.location="/login.cfm";
           </script>
     </cfif>
</cfif>

How do I direct the visitor to the blog article after they login instead of just going to the blog home page? Do I have to add a URL parameter?

Here is a sample link:
http://www.myblog.com/blog/index.cfm/2012/3/13/this-is-the-blog-article
ColdFusion Language

Avatar of undefined
Last Comment
kenjpete

8/22/2022 - Mon
ASKER CERTIFIED SOLUTION
_agx_

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
Chris Ashcraft

A typical session-based logon framework would be integrated with your application cfc. If implemented in this way any coldfusion templates in your application path will be caught by the logon mechanism when the page is requested in Application.cfc's onRequestStart. If not logged in they will be prompted to do so, then be directed to the appropriate page. If already logged in, they will bypass the logon prompt.

Here's a simple example...

Application.cfc...

<cfcomponent>
   <cffunction name="onRequestStart>
      <cfinclude template="logonAction.cfm">
   </cffunction>
</cfcomponent>

Open in new window


logonAction.cfm...

<cfif isDefined("logout")>
   <cfset SESSION.isLoggedIn = FALSE>
   <p><em>You have been logged out.</em></p>
</cfif>

<cfif isDefined("logon")>
   <cfif userIsAuthenticated(FORM.userid, FORM.password)>       <!---whatever do you to authenticate goes here--->
      <cfset SESSION.isLoggedIn = TRUE>
   <cfelse>
      <cfset SESSION.isLoggedIn = FALSE>
      <p><em>Invalid UserID or Password.</em><p>
   </cfif>
</cfif>

<cfif NOT structKeyExists(SESSION, "loggedIn") OR SESSION.loggedIn EQ FALSE>
   <cfinclude tempate="logonForm.cfm">
   <cfabort>
<cfelse>

Open in new window


logonForm.cfm...

<cfform action="#CGI.SCRIPT_NAME#">
   UserID: <cfinput type="text" name="userid"><br />
   Password: <cfinput type="text" name="password"></br>
   <cfinput type="hidden" name="logon" value="1">
   <cfinput type="submit" value="Log In" name="btnLogon">
</cfform>

Open in new window

_agx_

I'd agree real frameworks can make this kind of task easier, but it does require refactoring. However, that doesn't address the orig. question of how to redirect to a specific entry after login.

> isDefined("logon")

Also be sure to always scope variables (or preferably use structKeyExists) to avoid unintentional mishaps
Chris Ashcraft

My post is relevant in that the core problem here is in the logic behind his logon routine. If it were built properly there would be no need for a re-direct.

I agree that using StructKeyExists is best practice, but I don't see how that is relevent...
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
_agx_

My post is relevant in that the core problem here is in the logic behind his logon routine.

I don't disagree with the idea that there's better way of handling redirection (But I also don't know if they can or want to rewrite the code along these lines. That's up to them).

However the point is the code doesn't actually address the specific question that was asked. How to redirect to the previous url, not just how to create a generic login process. ie It's missing an example showing how to tie the two concepts together.

Edit: I disagree it's the core problem. They could easily make the existing code work by adding a url parameter. But I agree it's not very robust, and isn't the approach I'd use either.

If it were built properly there would be no need for a re-direct.
Strictly speaking, yes there would. It'd  just be handled differently.

I agree that using StructKeyExists is best practice, but I don't see how that is relevent...

Actually I said scoping or structKeyExists. Proper scoping to ensure the right result every time isn't "best practices" - its' the only practice IMO .. and correct code is always relevant ;-)
Chris Ashcraft

My intention was to convey how the logic of a properly-designed logon routine should be implemented - not a lesson on how to write CFML - but I think you know that. I agree that your solution would be a very quick and easy way to remedy their immediate need, but they should ultimately look into redesigning their logon framework.

However the point was the code doesn't actually address the specific question that was asked. How to redirect to the previous url, not just how to create a generic login process

By implementing a properly designed logon framework the issue of redirection will be eliminated, which will resolve the problem.
_agx_

but I think you know that.


Yep, I totally get it (and agree). But 1) I don't know what limitations they have. Sometimes people can't change things even when they should and 2) I was subtly trying to encourage you to show more code relevant to their situation to convince them why your method was better ;-) Just because you might understand something doesn't automatically mean your audience does too.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
kenjpete

ASKER
Thanks Guys! I really appreciate both of your input! I agree that this logon framework isn't the best approach. But, the reason I am doing it this way is because I am using BlogCFC for our blog software, and I was asked to add password-protection to it, along with a public page on the front end. So, I actually have the Application.cfm session scope that is part of BlogCFC and also my own Application.cfc file on the public part. This has complicated matters a bit for me.

Then, the whole e-mail newsletter feature got added. So I figured the easiest way to solve the linking problem was to probably add some sort of URL parameter and re-direct the user if the login is successful. My only concern with that is will the user be required to login several times in the same session of they click multiple links in that e-mail newsletter?

I will try the URL parameter approach and let you know how it goes, unless you have any other suggestions?
Chris Ashcraft

That makes since. _agx_'s code should work, but yes - I think you'll need to modify it to keep track of the logon state (like you were doing with the SESSION.auth.isLoggedIn variable)

Another thought...you don't necessarily have to implement the above logon framework in Application.cfc. Just modify the the following login.cfm and reference it at the top of every template using a cfinclude tag. It will automatically get called when you request your template. This can be easily reusable and there won't be any need for URL parameters or redirection...

blogwhatever.cfm

<cfinclude url="login.cfm">
.
.
blog code

Open in new window


login.cfm

   
   <!---log the user out - ?logoff URL parameter was passed--->
   <cfif structKeyExists(URL, "logoff")>
      <cfset SESSION.auth.isLoggedIn = FALSE>
      <p><em>Logged out.</em><p>
   </cfif>

   <!---log the user in - logon form was submitted--->
   <cfif structKeyExists(FORM, "logon")>   
      <cfif userIsAuthenticated(FORM.userid, FORM.password)>       <!---whatever do you to authenticate goes here--->
         <cfset SESSION.auth.isLoggedIn = TRUE>
      <cfelse>
         <cfset SESSION.auth.isLoggedIn = FALSE>
         <p><em>Invalid UserID or Password.</em><p>
      </cfif>
   </cfif>

   <!---if not logged in, show the logon prompt--->
   <cfif NOT structKeyExists(SESSION.auth, "isLoggedIn") OR SESSION.auth.isLoggedIn EQ true)>
             <!---Your logon form would go here--->
             <cfform action="#CGI.SCRIPT_NAME#">
             UserID: <cfinput type="text" name="userid"><br />
             Password: <cfinput type="text" name="password"></br>
             <cfinput type="hidden" name="logon" value="1">
             <cfinput type="submit" value="Log In" name="btnLogon">
         </cfform>
         <cfabort>
   </cfif>

Open in new window

kenjpete

ASKER
I was able to get the URL parameter approach working. If the site I was working with had a better framework for handling these URL re-directs I would have happily used the other approach suggested.
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck