<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Brenda on Life and other Quirky Bits &#187; projects</title>
	<atom:link href="http://blog.brendalogy.net/tag/projects/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.brendalogy.net</link>
	<description>The blog of Brenda Nicole Tan who is obsessed with design, code, photography and colourful balloons. (Well, that was random.)</description>
	<lastBuildDate>Mon, 23 Jan 2012 17:59:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Prevent automated registrations with JS</title>
		<link>http://blog.brendalogy.net/2011/2024/</link>
		<comments>http://blog.brendalogy.net/2011/2024/#comments</comments>
		<pubDate>Sat, 03 Sep 2011 20:40:27 +0000</pubDate>
		<dc:creator>brendalogy</dc:creator>
				<category><![CDATA[Interests]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[automated]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[gamemaki]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[submission]]></category>
		<category><![CDATA[usability]]></category>
		<category><![CDATA[user experience]]></category>

		<guid isPermaLink="false">http://blog.brendalogy.net/?p=2024</guid>
		<description><![CDATA[After GameMaki (one of my current pet projects) was hit by an onslaught of spam, I spent the last couple of hours thinking about how to prevent automated registrations. Originally, I attempted a very primitive method, which is to add a hidden field in the registration form which is set to &#8216;true&#8217; when the form [...]]]></description>
			<content:encoded><![CDATA[<p>After <a href="http://gamemaki.com" target="_blank">GameMaki</a> (one of my current pet projects) was hit by an onslaught of spam, I spent the last couple of hours thinking about how to prevent automated registrations.</p>
<p>Originally, I attempted a very primitive method, which is to add a hidden field in the registration form which is set to &#8216;true&#8217; when the form is loaded on a Javascript-enabled browser. When the form is submitted, this hidden field is checked for its value, and it only goes through when the value is &#8216;true&#8217;.</p>
<p>Obviously it hadn&#8217;t worked. It was too straightforward, and I&#8217;m pretty sure bots are much smarter than that.</p>
<p>So I thought, checking for whether the site was loaded in a standard browser wasn&#8217;t good enough. In order for a request to be human-initiated, there has to be some sort of interaction with the website &#8211; whether it is a <em>click</em>, <em>scroll</em> or <em>focus</em>.</p>
<p class="center"><img src="http://blog.brendalogy.net/wp-content/uploads/2011/09/04-09-2011.jpg" alt="jQuery slider by TheyMakeApps for form submission." /><br />
<em>jQuery slider by <a href="http://theymakeapps.com/users/add" target="_blank">TheyMakeApps</a> for form submission.</em></p>
<p><a href="http://theymakeapps.com/users/add" target="_blank">TheyMakeApps</a> has quite a cool implementation that requires some form of human interaction to successfully submit a form. Instead of a standard &#8216;click&#8217; to the submit button, their implementation requires the user to drag a slider to an end-point. jQuery is used to detect the position of the slider and the form will submit only when the slider has reached a certain point in the bar.</p>
<p>Quite nifty, but it didn&#8217;t feel natural. People are used to hitting &#8216;tab&#8217; when navigating from one form field to another, before a final &#8216;tab&#8217; and an &#8216;enter&#8217; to submit a form. </p>
<p>I didn&#8217;t want to yank users out of their comfort zone. So, how do I check for automated registrations without imposing any additional burden to the user? (And quite obviously, <a href="http://en.wikipedia.org/wiki/CAPTCHA" target="_blank"><abbr title="Completely Automated Public Turing test">CAPTCHAs</abbr></a> are out of the question.)</p>
<p>Here&#8217;s how I eventually did it. Well, it still involves a hidden field, for sure.</p>
<p>Place a hidden field in your form as follows. This field has a unique ID of &#8216;botcheck&#8217; with a default value of &#8216;false&#8217;.</p>
<blockquote><p><code>&#60;input type="hidden" name="botcheck" id="botcheck" value="false" /&#62;</code></p></blockquote>
<p>Now, what we need is a bit of Javascript and jQuery.</p>
<p>I have two functions in my Javascript file. The first function, randomString() generates a random string of numbers to populate the hidden field with. The second is the validation function which will be called when the form is submitted. On top of that, we have one global variable to track the value of the generated random string.</p>
<blockquote><p><code>// Global variable<br />
var randomstring = "";</code></p>
<p><code>// Function to generate a random string<br />
function randomString() {<br />
&nbsp;&nbsp;var chars = "0123456789ABCDEFGHIJKLMNO<br />
PQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";<br />
&nbsp;&nbsp;var string_length = 8;<br />
&nbsp;&nbsp;for (var i=0; i&#60;string_length; i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;var rnum = Math.floor(Math.random() * chars.length);<br />
&nbsp;&nbsp;&nbsp;&nbsp;randomstring += chars.substring(rnum,rnum+1);<br />
&nbsp;&nbsp;}<br />
}</code></p>
<p><code>// Function to verify hidden field value</em><br />
function doBotCheck() {<br />
&nbsp;&nbsp;var botcheckfield = $('#botcheck').val();<br />
&nbsp;&nbsp;if (botcheckfield == randomstring) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;return true;<br />
&nbsp;&nbsp;} else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;alert("Hello, robot!");<br />
&nbsp;&nbsp;&nbsp;&nbsp;return false;<br />
&nbsp;&nbsp;}<br />
}<br />
</code></p>
<p>Note: Credit for the <em>randomString()</em> function goes to <a href="http://www.mediacollege.com/internet/javascript/number/random.html" target="_blank">MediaCollege</a>.</p></blockquote>
<p>Now that we have all our Javascript functions ready, let&#8217;s add a bit of jQuery magic.</p>
<p>On document load, a random string will be generated. A &#8216;focus&#8217; event is bound to all my form&#8217;s input fields. When this event is triggered, the hidden field is populated with the random string. </p>
<p>I chose the &#8216;focus&#8217; event as it requires manual user interaction with the form to verify that the user of the form is <em>indeed a human</em>. (Originally, I contemplated using the &#8216;change&#8217; event but decided against it since the fields can be directly manipulated via a script anyway.)</p>
<p>The use of a random string ensures that the value of the hidden field will not be easy to guess if the spammer wanted to directly manipulate it.</p>
<p>So, we have this.</p>
<blockquote><p><code>//Populate hidden field only when user triggers a manual interaction with the form<br />
$(document).ready(function() {<br />
&nbsp;&nbsp;// Generate a random string<br />
&nbsp;&nbsp;randomString();</code></p>
<p><code> &nbsp;&nbsp;// Update hidden field on field focus<br />
&nbsp;&nbsp;$('#MyForm input').live('focus', function() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;$('#botcheck').val(randomstring);<br />
&nbsp;&nbsp;});<br />
});</code></p></blockquote>
<p>Last but not least, remember to call the validation function from your form on submit. </p>
<blockquote><p><code>&#60;form id="MyForm" onSubmit="return doBotCheck()" method="POST"&#62;</code></p></blockquote>
<p>And <em>wa-laaaaah</em>.</p>
<p>Well, this is my method for now. Whether it works, I&#8217;ll just have to wait and see. If you see any flaws in my method, don&#8217;t hesitate to holler. And if you&#8217;ve better ideas on how to solve this problem, feel free to share &#8216;em!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brendalogy.net/2011/2024/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>It does not pay to be neat but forgetful</title>
		<link>http://blog.brendalogy.net/2011/1999/</link>
		<comments>http://blog.brendalogy.net/2011/1999/#comments</comments>
		<pubDate>Sat, 02 Jul 2011 08:35:33 +0000</pubDate>
		<dc:creator>brendalogy</dc:creator>
				<category><![CDATA[Daily Life]]></category>
		<category><![CDATA[Funny Stuff]]></category>
		<category><![CDATA[absent-minded]]></category>
		<category><![CDATA[behaviour]]></category>
		<category><![CDATA[craft]]></category>
		<category><![CDATA[DIY]]></category>
		<category><![CDATA[forgetful]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[quirky]]></category>
		<category><![CDATA[wacky]]></category>

		<guid isPermaLink="false">http://blog.brendalogy.net/?p=1999</guid>
		<description><![CDATA[Two weeks ago, I bought about a foot worth of white cloth as I had a pair of jeans I wanted to patch. However, I was way too busy at that time and left that folded piece of white cloth somewhere on my desk. Directly within sight, so that I&#8217;d remember to fix my jeans. [...]]]></description>
			<content:encoded><![CDATA[<p>Two weeks ago, I bought about a foot worth of white cloth as I had a pair of jeans I wanted to patch.</p>
<p>However, I was way too busy at that time and left that folded piece of white cloth somewhere on my desk. Directly within sight, so that I&#8217;d remember to fix my jeans.</p>
<p>A few days later, my <em>neat freak</em> streak got the better of me and I decided to declutter my desk. I ended up placing the white cloth somewhere else in my room.</p>
<p>Now, I want to fix my jeans and have <em>no freaking clue</em> where the cloth is, despite racking my brains for almost three days.</p>
<p><abbr title="Fuck My Life">FML</abbr>. Welcome to my world.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brendalogy.net/2011/1999/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Protected: Revelations</title>
		<link>http://blog.brendalogy.net/2010/1892/</link>
		<comments>http://blog.brendalogy.net/2010/1892/#comments</comments>
		<pubDate>Tue, 09 Nov 2010 03:19:12 +0000</pubDate>
		<dc:creator>brendalogy</dc:creator>
				<category><![CDATA[Daily Life]]></category>
		<category><![CDATA[commitments]]></category>
		<category><![CDATA[company]]></category>
		<category><![CDATA[decisions]]></category>
		<category><![CDATA[introspective]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.brendalogy.net/?p=1892</guid>
		<description><![CDATA[There is no excerpt because this is a protected post.]]></description>
			<content:encoded><![CDATA[<div class="protectedpost">
<form action="http://blog.brendalogy.net/wp-pass.php" method="post">
<p>Password protected post. Please enter the password to view:</p>
<p>
<input name="post_password" id="pwbox-1892" type="password" size="40" />
<input type="submit" name="Submit" class="submit nomargin" value="Submit" /></p></form>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.brendalogy.net/2010/1892/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

