New and Improved--now built with LylaCaptcha!

Posted by Dan on Jun 27, 2006 @ 10:22 PM

In order to try and prevent the spamming issues, I finally had to do something I didn't want to do—and that's implement a Captcha process to the comments.

When you wish to post a comment, you'll now be required to fill in the text you see in the image right below the comment box. This is to help ensure that it's a real person entering in the comment and not just a spam bot. If this doesn't help with the problem, the next step will be either to require a valid e-mail (in which you'll have to go through a verify process the first time you post) or I'll start approving all comments manually. I really hope I don't have to turn off commenting altogether, but I'm tired of deleting 20-30 spam messages a day.

For those of you wondering, I used LylaCaptcha for my captcha needs, which worked on really well. I was going to type up a "how-to", as the documents on the LylaCaptcha site aren't as straightforward as they could be. Once you figure out what you need to do, it's very straightforward, but I found I had to really do a lot through trial an error. Anyway, the reason I'm not doing a write-up is Brian Rinaldi already wrote what I ended up doing in a blog post titled Adding Open-Source LylaCaptcha to BlogCFC.

Don't let that title fool you though, he shows the basic code that's needed to add LylaCaptcha to any of your projects. I just wish I would have found this article before I wrote my code. It would have saved me a lot of trial and error.

NOTE:

There are a couple of issues I found with LylaCaptcha.

  • The captchaService.cfc must be stored as a persistent variable (application scope, server scope, etc.) This is because it uses a caching algorithm for the hashes. If you only initiate the CFC as a local variable, the results will only be valid for that page. So, if you wish to use a setup like Brian documents in his blog post, make sure to use the application scope.
  • If you're on CFMX 6.x, you'll need to remove references to the function isXML() found in the captchaService.cfc. I believe there's only one call to this function. This is a function new to CFMX 7. You can just comment this block of code out—doing so should not harm your code in the least, all it will do is give you less specific error checking if you captcha.xml is invalid.
  • This is documented on the LylaCaptcha website. Line 248 that currently reads:

    <cfset graphics.setColor(getConfigBean().getFontColor()) />

    Should read:

    <cfset graphics.setColor(getColorByType(getConfigBean().getFontColor())) />
Categories: Personal, HTML/ColdFusion

18 Comments

  • Glad that you implemented Lyla. As you know, the project is still alpha-ware at the moment. A newer version is coming soon with better support for i18n and to fix little bugs.

    1. Yes, the captchaService.cfc must me in a persistent scope. I have made sure that newest documentation (which I haven't released yet) will state that clearly.
    2. The isXML() call has been removed for wider application platform support. The things you forgot when you move to newer versions.
    3. The bug in regards to setColor() has been fixed in the future releases.

    Even better is the Lyla/AjaxCFC article that Brian wrote for CFDJ. Look for it soon!

    Best,
    .Peter J. Farrell
  • Peter,

    Great work you put in to LylaCaptcha. It certainly would have taken much more of my time to roll out my own solution. With the changes you've made, I'm sure it'll make it even easier to implement.

    It really is easy to use, it was just the few gotchas that I mentioned that took me time to track down. Now that I know what needs to be done, it wouldn't take me but a few minutes to implement the code again.

    One suggestion I'd like to see is maybe the use of a dictionary file. Instead of using a random string, it would use a random word from the dictionary (probably should only contain words somewhere between 4-8 characters long.) While not as secure, provided the dictionary is large enough, it should prove secure enough. Heck, you might even make the dictionary of words 3-5 characters long and then combine two words together.

    Anyway, great work on the project and thanks for all your hard work!

    -Dan
  • Gents,

    I'm attempting to use lyla but I'm unsure as to how to set the captchaService.cfc as persistant scope. My application.cfm looks like this:




    My index.cfm looks like this:




     
    Captcha text:
     

     

     



    and my showCaptcha.cfm looks like this:



    Yet my image always states that the captcha isn't available. Could anyone help?

    Cheers

    J
  • @J:

    Here's an example of how to configure things so the application scope only gets initialized when it doesn't already exist in memory:

    <cflock scope="application" type="readonly" timeout="10">
         <cfset bAppInit = structKeyExists(application, "init") />
    </cflock>

    <cfif NOT bAppInit OR (structKeyExists(url, "reinit") and (url.reinit eq true))>
         <cflock scope="application" type="exclusive" timeout="30">
              <cfscript>
              application.init = true;

              // create the captcha service object
              application.oCaptchaService = createObject("component", "captchaService").init(configFile="captcha.xml");
              // set up the captcha component
              application.oCaptchaService.setup();
              </cfscript>
         </cflock>
    </cfif>
  • How did you get the captcha to display in ie 7. While mine works in ie 6, it doesn't in ie 7. I've tried a mime type of image/jpg and image/jpeg with no success. Yours does work in ie 7. Thanks.
  • @Tom,

    Here's what I use to display the code:

    <!---// display and delete the image //--->
    <cfcontent type="image/jpg" file="#oCaptcha.fileLocation#" deletefile="true" reset="true" />

    -Dan
  • Thanks. Further testing (with delete="false" in the cfcontent line) shows that two captcha images are created each time I go to the page (from IE 7) (http://www.howellnaz.org/captcha/captcha.cfm), a correct one and one showing the captcha not available message (which is displayed). Could something be causing the double image creation, in which case, the second one's hash would not be able to be successfully looked up?

    From IE 6 and FF 2 on my other computer, only 1 image is created, a correct one, and is displayed.


    My test captcha.cfm is

    <CFIF isdefined('form.captchahash')><CFOUTPUT>From form: #application.captcha.validateCaptcha(form.captchaHash,form.captchaText)#<BR></CFOUTPUT></CFIF>

    <!--- captcha validation --->
    <CFIF isdefined('form.captchaText')>
    <CFSET errorStr = "">
    <cfif not len(form.captchaText)>
      <cfset errorStr = errorStr & "Please enter the Captcha text.<br>">
    <cfelseif application.captcha.validateCaptcha(form.captchaHash,form.captchaText) IS "NO">
      <cfset errorStr = errorStr & "The captcha text you have entered is incorrect.<br>">
    </cfif>
    <CFOUTPUT>#errorStr#</CFOUTPUT>
    </CFIF>

    <cfset application.captcha = CreateObject("component","captchaService").init(configFile="captcha.xml") />
    <cfset application.captcha.setup() />
    <cfset variables.captcha = application.captcha.createHashReference() />

    <BR>

    <FORM ACTION="captcha.cfm" METHOD="POST">
    <CFOUTPUT>
    <img src="#website_url#captcha/captchadisplay.cfm?hashReference=#variables.captcha.hash#" /><BR>
    <INPUT TYPE="Text" NAME="captchaHash" VALUE="#variables.captcha.hash#" SIZE="55"><BR> #variables.captcha.text#
    Authenticate: <INPUT TYPE="Text" NAME="captchaText" VALUE="" SIZE="10">
    </CFOUTPUT>
    <INPUT TYPE="Submit" VALUE="Submit">
    </FORM>




    My captchadisplay.cfm is

    <cfset variables.captcha = application.captcha.createCaptchaFromHashReference("file",url.hashReference) />
    <cfcontent type="image/jpeg" file="#variables.captcha.fileLocation#" deletefile="false" reset="false" />
  • Well, the code didn't display.
  • I think I may have figured out what's going on. The computer with IE 7 is running Trend Micro PCcillin's anti-spyware web filter. When I turn that off, the captcha shows correctly (and only 1 image is generated). When I turn it back on, two images are generated, the second being "captcha not available", the problem I was seeing. Turn it off again, and it works again.

    Could the dynamic image reference such as
    img src="#website_url#captcha/captchadisplay.cfm?hashReference=#variables.captcha.hash#"
    be a problem for the spyware detector?

    Anyway, in that case, I need to refer to the image differently, I think, somehow.

    Any ideas to work around such spyware filters?

    Tom
  • I should remind you that your captcha displays whether or not the spyware filter is on. So, the way in which I refer to the image in the img tag may be the issue?

    #website_url#captcha/captchadisplay.cfm?hashReference=#variables.captcha.hash#
  • @Tom,

    I'd recommend using an HTTP Proxy filter to actually monitor the HTTP traffic. I'm wonder HTTP call to the image is being called multiple times--like PCcillin is pre-fecthing the content and then IE is grabbing it again.

    I'm not sure why 2 different images would be created though...
  • @Tom,

    One other idea, maybe it's a locking issue. Wrap your createCaptchaFromHashReference() call in cflock tags.

    In my code I make a locked copy of the Captcha object in the Request scope.

    If you are getting double calls to the page, it could be a asynchronous issue. Locking would fix that.
  • Dan, are you using createCaptchaFromHashReference or just createCaptcha somehow?

    When I use createCaptcha, I can get the captcha to be displayed but haven't figured out how to match it to the text. But, createCaptchaFromHashReference is still creating the two images on that computer even with a lock in place.
  • @Tom:

    You might try contacting Peter Farrell. Perhaps you're using a different version of Captcha. I know I did make a few changes to the CFC (to fix some other issues.)

    The id of one I'm using is:

    $Id: captchaService.cfc 3221 2006-04-10 21:13:04Z pfarrell $

    However, I know I made a few tweaks to the code to fix known issues at the time.
  • pls , can anyone can help ?
    i can't get it work with my hosting server coz it still in CFMX6, i already deleted the "isxml()" function from the captchaservice.cfm file, still can not display the image... :( anyone can help me? i use the newest version (0.2alpha) and the example code on this site:
    http://www.dervishmoose.com/blog/index.cfm/2006/9/...

    i just replace the "stream" function from the chaptchaimg.cfm file to "file" function like this:



    coz it said that the "stream" cannot support in CFMX 6 (only CFMX7), so i use the "file" function... i've been searching for it to support in cfmx 6 but still, can't ><
  • i think i create a typo before this comment TT, anyway... corrected line:
    i just replace the "stream" function from the chaptchaimg.cfm file to "file" function like this:

    cfset variables.captcha = application.captcha.createCaptchaFromHashReference("file",url.hashReference)

    cfcontent type="image/jpg" file="#variables.captcha.fileLocation#" deletefile="true" reset="false"

    (removed the "<" and ">" to display it properly)
  • Erorr In IE 7.0
  • i like this captcha, maybe we will implement the same approach on our site.

Comments for this entry have been disabled.