<?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>The Wojo Group &#187; authentication</title>
	<atom:link href="http://www.thewojogroup.com/tag/authentication/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thewojogroup.com</link>
	<description>The musings of a small creative media company.</description>
	<lastBuildDate>Tue, 11 May 2010 00:10:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Remember Me&#8217;s with Rails</title>
		<link>http://www.thewojogroup.com/2008/09/remember-mes-with-rails/</link>
		<comments>http://www.thewojogroup.com/2008/09/remember-mes-with-rails/#comments</comments>
		<pubDate>Fri, 26 Sep 2008 18:51:13 +0000</pubDate>
		<dc:creator>Brett Wejrowski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[expiration]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[remember me]]></category>
		<category><![CDATA[RoR]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[session]]></category>

		<guid isPermaLink="false">http://www.thewojogroup.com/?p=150</guid>
		<description><![CDATA[I recently had a need for a login system that needed a 'remember me' function.  After hours of looking through countless blogs, I came to the conclusion that either (1) people don't use a remember me function with Rails logins, or (2) they don't write about it.  In this article, I outline a simple remember me system using the cookie variable in Rails that will tack on to most custom authentication systems.  ]]></description>
			<content:encoded><![CDATA[<p>I recently had a need for a login system that <em>needed </em>a &#8216;remember me&#8217; function.  After hours of looking through countless blogs, I came to the conclusion that either (1) people don&#8217;t use a remember me function with custom authentication systems for Rails, or (2) they don&#8217;t talk about it.  In this article, I outline a simple remember me system using the <span style="color: #008000;">cookie</span> variable in Rails that will tack on to most custom authentication systems.</p>
<p>Using the <span style="color: #008000;">cookie</span> functions in Rails is pretty <a href="http:/http://api.rubyonrails.org/classes/ActionController/Cookies.html" target="_blank">straightforward.</a> It&#8217;s used with the ActionController and is quite simple to use.  Most people use <span style="color: #008000;">sessions </span>for authentication, which is a good idea.  <span style="color: #008000;">Sessions</span>, unlike cookies, automatically save your content as encrypted strings using the browsers cookies. ActionController#<span style="color: #008000;">cookie</span> provides a method for saving information in the browser, but you need to hash the content yourself if need be.</p>
<p>However, if a user selects the remember me option when logging in, we would like to have the <span style="color: #008000;">session</span> expiration set to be a longer period, like 30 days.  Unfortunately, this is quite difficult to do if you don&#8217;t want to change the expiration of ALL sessions.</p>
<p>My site already uses <span style="color: #008000;">sessions</span> for authentication, and I&#8217;m going to leave that be.  In fact, I&#8217;m not going to change anything about the <span style="color: #008000;">session</span> variable <em>at all. </em>This way, I can add this remember function to almost any authentication system I use in the future very easily.</p>
<p>When a user is authenticated and has selected the &#8220;remember me&#8221; option, I do two things:</p>
<p>- create a cookie that stores (<strong>plain text</strong>) the user&#8217;s <span style="color: #ff0000;">id</span><span style="color: #ff0000;"> </span>(you can use name, email, etc. but I prefer the id because it says nothing about the user to anyone trying to get information)</p>
<p>- create a second cookie with an <strong>hashed string</strong> of some other information about the user( name, email, address )</p>
<pre name="code" class="ruby">
if params[:rememberMe]
userId = (@user.id).to_s
cookies[:remember_me_id] = { :value =&gt; userId, :expires =&gt; 30.days.from_now }
userCode = Digest::SHA1.hexdigest( @user.email )[4,18]
cookies[:remember_me_code] = { :value =&gt; userCode, :expires =&gt; 30.days.from_now }
end
</pre>
<p>For the hashing of the second piece of information, use a hash such as SHA1 or MD5.  We can use these two cookies to authenticate a user when they return after a session has expired.</p>
<pre name="code" class="ruby">
if ( cookies[:remember_me] and cookies[:remember_me] and User.find( cookies[:remember_me]) and Digest::SHA1.hexdigest( User.find( cookies[:remember_me] ).email )[4,18] == cookies[:remember_me_code]  )
@u = User.find( cookies[:remember_me_id] )
session[&#039;user&#039;] = @u.id
end
</pre>
<p>Just work that into your <span style="color: #ff9900;">:before_filter</span> for your authentication system, and you&#8217;re all set.  Make sure you delete the variables when someone logs out:</p>
<pre name="code" class="ruby">
if cookies[:remember_me_id] then cookies.delete :remember_me_id end
if cookies[:remember_me_code] then cookies.delete :remember_me_code end
</pre>
<p>****Edit: make sure to have &#8220;require &#8216;digest/sha1&#8242;&#8221; at the top of any page where you are using the SHA1 hash.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thewojogroup.com/2008/09/remember-mes-with-rails/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Simple login with Rails</title>
		<link>http://www.thewojogroup.com/2008/09/super-simple-login-with-rails/</link>
		<comments>http://www.thewojogroup.com/2008/09/super-simple-login-with-rails/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 15:47:39 +0000</pubDate>
		<dc:creator>Brett Wejrowski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[beta]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[Motionspire]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[RoR]]></category>
		<category><![CDATA[user]]></category>

		<guid isPermaLink="false">http://www.thewojogroup.com/?p=121</guid>
		<description><![CDATA[We recently beta launched a new site, motionspire.com.  Our main goal for the launch was to get statistics from user testing, mainly from a targeted audience.  In order to keep a limited user base, we wanted to make visitors create a beta account, and use a login system in order to view the site.

I wanted to create a quick and simple login system that was, most importantly, temporary.  The authentication didn't require a lot of security because no user information was stored in our db other than an email and password.  I also wanted to contain all the code for the system (as much as possible at least) in a few different directories, so I can easily remove the system for the main launch.]]></description>
			<content:encoded><![CDATA[<p>We recently beta launched a new site, motionspire.com.  Our main goal for the launch was to get statistics from user testing, mainly from a targeted audience.  In order to keep a limited user base, we wanted to make visitors create a beta account, and use a login system in order to view the site.</p>
<p>I wanted to create a quick and simple login system that was, most importantly, temporary.  The authentication didn&#8217;t require a lot of security because no user information was stored in our db other than an email and password.  I also wanted to contain all the code for the system (as much as possible at least) in a few different directories, so I can easily remove the system for the main launch.</p>
<p>Here is the process I wanted to create:</p>
<ol>
<li>1. user comes to the site, and inputs an email address requesting a beta account</li>
<li>2. the user gets an email with (1) a link to create their password and (2) a code for authentication</li>
<li>3. the user inputs the code and creates their password</li>
<li>4. the user can now view the site, and login at a later time</li>
</ol>
<p>So that&#8217;s the process.  My designer created two pages: (1) a page with a form requesting an account and another form to login and (2) a page to create a password with the code.  I created a new controller, beta, and started with these two functions:</p>
<pre name="code" class="ruby">
&lt;span style=&quot;color: #333399;&quot;&gt;&gt; ruby script/generate controller beta index create_password&lt;/span&gt;
</pre>
<p>And I created a model, betauser:</p>
<pre name="code" class="ruby">
&lt;span style=&quot;color: #333399;&quot;&gt;&gt; ruby script/generate model betauser&lt;/span&gt;
</pre>
<p>The model had three fields: email, password, and a boolean &#8216;active&#8217; to keep track of whether the user had activated the account. I usually use the timestamps for every model just as good practice.  Here is the migration:</p>
<pre name="code" class="ruby">
&lt;span style=&quot;color: #333399;&quot;&gt;class AddBetaUsers &lt; ActiveRecord::Migration
def self.up
create_table :betausers do |t|
t.boolean :active
t.string :email, :password
t.timestamps
end
end&lt;/span&gt;
</pre>
<pre name="code" class="ruby">
&lt;span style=&quot;color: #333399;&quot;&gt; def self.down
drop_table :betausers
end
end&lt;/span&gt;
</pre>
<p>Next was the function for requesting a beta account.  The form&#8217;s only input was their email:</p>
<pre name="code" class="ruby">
&lt;span style=&quot;color: #333399;&quot;&gt;def create_beta_invite
email = params[:email]
beta = Betauser.new
&lt;/span&gt; &lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt; //set the account to inactive
&lt;/span&gt; &lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt; beta.active = false
beta.email = email
if beta.save
&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// create a code based on the users email
// its not the most secure way to do things,
// but its simple and doesnt require another
// field in the database&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;
code = Digest::SHA1.hexdigest(email)[3,12]
&lt;/span&gt; &lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;
// create an email with my ActiveMailer model &#039;Notifier&#039;
&lt;/span&gt; &lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt; email = Notifier.create_beta(email,code)
email.set_content_type(&quot;text/html&quot;)
Notifier.deliver(email)
&lt;/span&gt; &lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt; //redirect to the password creation page
&lt;/span&gt; &lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt; redirect_to :action =&gt; &quot;create_password&quot;,
:email =&gt; email
[sourcecode language=&quot;ruby&quot;]&lt;span style=&quot;color: #333399;&quot;&gt; else
redirect_to :action =&gt; &quot;index&quot;
end
end&lt;/span&gt;
</pre>
<p></span>[/sourcecode]</p>
<pre name="code" class="ruby">
After the user gets their email with their activation code, they go to the create_password page.  I send the email as a param in the link, so the activation page will only work if they use the link in the email (or directly edit the address if they are real crafty). The create password page has 3 inputs: code, password, and passRepeat (to verify the password).  Here is the action for this form:
</pre>
<pre name="code" class="ruby">
[sourcecode language=&quot;ruby&quot;]&lt;span style=&quot;color: #333399;&quot;&gt;def make_account
@beta = Betauser.find_by_email(params[:email])
if !@beta
redirect_to :action =&gt; &quot;index&quot;
&lt;/span&gt; &lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt; //check that password fields match
&lt;/span&gt; &lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt; elsif params[:password] == params[:passRepeat] &lt;/span&gt; &lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt; &lt;/span&gt;&lt;/em&gt;
</pre>
<p>[/sourcecode]</p>
<pre name="code" class="ruby">
[sourcecode language=&quot;ruby&quot;]&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt; // check that the code matches our formula from before
&lt;/span&gt; &lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt; if params[:code] != Digest::SHA1.hexdigest(@beta.email)[3,12]
flash[:alert] = &quot;Incorrect Code!&quot;
redirect_to :action =&gt; &quot;create_password&quot;,
:email =&gt; @beta.email
else
&lt;/span&gt; &lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt; //save the password
&lt;/span&gt; &lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt; @beta.password = Digest::SHA1.hexdigest(params[:password])
&lt;/span&gt; &lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt; //set the account to active
&lt;/span&gt; &lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt; @beta.active = true
@beta.save
&lt;span style=&quot;color: #999999;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;//use the session cookies to log the user in,
// then redirect to the site&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;&lt;span style=&quot;color: #999999;&quot;&gt;
&lt;/span&gt; session[&#039;betauser&#039;] = @beta.id
redirect_to :controller =&gt; &quot;main&quot;,
:action =&gt; &quot;index&quot;
end
else
flash[:alert] = &quot;Passwords do not match!&quot;
redirect_to :action =&gt; &quot;create_password&quot;,
:email =&gt; @beta.email
end
end
&lt;/span&gt;
</pre>
<p>So now we have a user logged in.  But we have to have a &#8216;gatekeeper&#8217; function to allow logged in users to view the site, and send everyone else to the login page.  We will put this in the application.rb controller:[/sourcecode]</p>
<pre name="code" class="ruby">
[sourcecode language=&quot;ruby&quot;]&lt;span style=&quot;color: #999999;&quot;&gt; &lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// run the function before every action in our app&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;&lt;span style=&quot;color: #999999;&quot;&gt;
&lt;/span&gt; before_filter :check_beta
....
protected
....&lt;/span&gt;
</pre>
<p>[/sourcecode]</p>
<pre name="code" class="ruby">
&lt;span style=&quot;color: #333399;&quot;&gt;def checkbeta
&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// don&#039;t check when user is in the beta pages
// that will cause an infinite redirect loop&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;
if controller_name != &#039;beta&#039;
&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// if betauser session variable is there
// and the beta user exists, set a
// global @betauser to represent the user&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;
if (session[&#039;betauser&#039;] and Betauser.find(session[&#039;betauser&#039;]) )
@betauser = Betauser.find(session[&#039;betauser&#039;])
&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// if the account has not been activated,
// send the user to the create password page&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;
if @betauser.active == false
session[:original_uri] = request.request_uri
redirect_to :controller =&gt; &quot;beta&quot;,
:action =&gt; &quot;create_password&quot;,
:email =&gt; @betauser.email
end
else
&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// if a user is not logged in,
// store the requested call
// and send the user to the
// account request and login page&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;
session[:original_uri] = request.request_uri
redirect_to :controller =&gt; &quot;beta&quot;,
:action =&gt; &quot;index&quot;
end
end
end&lt;/span&gt;
</pre>
<p>Notice that if the user is logged in and the account is active, there is no redirect, and the user goes to the requested page.</p>
<p>The only thing left is to create a login and logout function in our beta controller:</p>
<pre name="code" class="ruby">
&lt;span style=&quot;color: #333399;&quot;&gt;def login
password = params[:password]
email = params[:email]
user = Betauser.find_by_email(email)
&lt;span style=&quot;color: #999999;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// make sure the user exists&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;&lt;span style=&quot;color: #999999;&quot;&gt;
&lt;/span&gt; if !user
flash[:alert] = &quot;No user with that email address.&quot;
redirect_to :action =&gt; &quot;index&quot;
&lt;span style=&quot;color: #999999;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// make sure the account is active&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;&lt;span style=&quot;color: #999999;&quot;&gt;
&lt;/span&gt; elsif user.active == 0
flash[:alert] = &quot;You must activate your beta account.&quot;
redirect_to :action =&gt; &quot;create_password&quot;,
:email =&gt; user.email
&lt;span style=&quot;color: #999999;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// verify the password&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;&lt;span style=&quot;color: #999999;&quot;&gt;
&lt;/span&gt; elsif Digest::SHA1.hexdigest(password) != user.password
flash[:alert] = &quot;Incorrect Password.&quot;
redirect_to :action =&gt; &quot;index&quot;
else
&lt;span style=&quot;color: #999999;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// set the session variable to log the user in&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;&lt;span style=&quot;color: #999999;&quot;&gt;
&lt;/span&gt; session[&#039;betauser&#039;] = user.id
&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// send to the original request, if exists
// otherwise, send to the homepage&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;
if session[:original_uri]
redirect_to session[:original_uri]
else
redirect_to :controller =&gt; &quot;main&quot;,
:action =&gt; &quot;index&quot;
end
end
end&lt;/span&gt;
</pre>
<pre name="code" class="ruby">
&lt;span style=&quot;color: #333399;&quot;&gt;def logout
&lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: #333399;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #999999;&quot;&gt;// set the session variable to nil
// and redirect to the login page&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: #333399;&quot;&gt;
session[&#039;betauser&#039;] = nil
redirect_to :controller =&gt; &quot;beta&quot;,
:action =&gt; &quot;index&quot;
end&lt;/span&gt;
</pre>
<p>That&#8217;s about it.  There are definitely things I could have done better, but I wanted something quick, dirty, and temporary.  It works, and is not something I would want to use long term.  However, if you have a need for a low-security, simple login, this gets it done.  Overall, it only took me about an hour and 15 minutes to code, and will be very simple to remove.</p>
<p>**I will follow up with a very simple removal of the system, and post the files in their entirety at a later time.  Check it out at <a href="http://motionspire.com">Motionspire.com!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thewojogroup.com/2008/09/super-simple-login-with-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
