<?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>Binary Logic &#187; Authlogic</title>
	<atom:link href="http://www.binarylogic.com/tag/authlogic/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.binarylogic.com</link>
	<description>Ben Johnson's thoughts and programming techniques</description>
	<lastBuildDate>Sat, 23 Jan 2010 21:19:58 +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>Authlogic: keeping you in the loop</title>
		<link>http://www.binarylogic.com/2009/11/21/authlogic-keeping-you-in-the-loop/</link>
		<comments>http://www.binarylogic.com/2009/11/21/authlogic-keeping-you-in-the-loop/#comments</comments>
		<pubDate>Sat, 21 Nov 2009 22:17:43 +0000</pubDate>
		<dc:creator>benjohnson</dc:creator>
				<category><![CDATA[Authlogic]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[v3]]></category>

		<guid isPermaLink="false">http://www.binarylogic.com/?p=820</guid>
		<description><![CDATA[I figured I would post an update keeping everyone in the loop. I created a new branch for authlogic locally and I&#8217;ve been making some changes mentioned in this post. Some of the changes I&#8217;m making are still somewhat experimental and I&#8217;m playing around with the code to see if I like the end result. [...]]]></description>
			<content:encoded><![CDATA[<p>I figured I would post an update keeping everyone in the loop. I created a new branch for authlogic locally and I&#8217;ve been making some changes mentioned <a href="http://www.binarylogic.com/2009/08/13/authlogic-ideas/">in this post</a>. Some of the changes I&#8217;m making are still somewhat experimental and I&#8217;m playing around with the code to see if I like the end result. Figuring out a way to make this ORM agnostic has proven difficult, simply because there is no standard. They all follow a similar pattern, but the method naming conventions and some of the feature implementations are vastly different. I&#8217;m also not sure you could even set a standard. Regardless, I do think this is an important feature since there is a lot of movement around alternative storage solutions such as MongoDB, CouchDB, etc.</p>
<p>Splitting out some of the authentication code into &#8220;authenticators&#8221; has worked out great so far. More importantly, its more or less a blueprint for people to extend Authlogic and provide alternate authentication solutions (openid, facebook connect, oauth, etc.).</p>
<p>The last major change I&#8217;ve been making is removing validations in the acts_as_authentic module. Validations add some clutter to authlogic, some might say its a necessary clutter, but I&#8217;m leaning towards leaving it out. Validation is such an easy thing to do. ActiveRecord provides very simple methods for doing this, I also feel like its gets in the way for certain edge cases. Authlogic will still provide some nice methods to make your life easier, like validating the format of an email address, the main difference being that you have to explicitly implement this validation. No validations will be automatically added. Lastly, this makes ORM abstraction a little easier.</p>
<p>So that&#8217;s that. I&#8217;ll keep you updated when I start to push out some code and what not. I&#8217;m probably going to label this release as v3, because of the validation changes and some of the other major changes that might break backwards compatibility.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binarylogic.com/2009/11/21/authlogic-keeping-you-in-the-loop/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Authlogic generators? All of the cool kids are doing it.</title>
		<link>http://www.binarylogic.com/2009/04/17/authlogic-generators-all-of-the-cool-kids-are-doing-it/</link>
		<comments>http://www.binarylogic.com/2009/04/17/authlogic-generators-all-of-the-cool-kids-are-doing-it/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 07:29:46 +0000</pubDate>
		<dc:creator>benjohnson</dc:creator>
				<category><![CDATA[Authlogic]]></category>
		<category><![CDATA[base app]]></category>
		<category><![CDATA[generators]]></category>
		<category><![CDATA[rails templates]]></category>

		<guid isPermaLink="false">http://www.binarylogic.com/?p=677</guid>
		<description><![CDATA[Lately I&#8217;ve been getting a lot of pressure to add a generator to Authlogic. One of the big things I &#8220;tout&#8221; about Authlogic is the fact that is does not need generators, not anymore than any other RESTful controller you create. Authlogic can pull this off because it&#8217;s intuitive, it works just like every other [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-679 alignleft" title="peer_pressure" src="http://www.binarylogic.com/wp-content/uploads/2009/04/peer_pressure.jpg" alt="peer_pressure" width="150" height="107" />Lately I&#8217;ve been getting a lot of pressure to add a generator to Authlogic. One of the big things I &#8220;tout&#8221; about Authlogic is the fact that is does not need generators, not anymore than any other RESTful controller you create. Authlogic can pull this off because it&#8217;s intuitive, it works just like every other model you have in your application. Unless you want to customize how it works, there&#8217;s no learning curve. If you know how to set up a RESTful controller for an ORM model, then you know how to set up a RESTful controller for an Authlogic model.</p>
<p><span id="more-677"></span>In my opinion generators are meant to be a starting point for repetitive tasks that have no sustainable pattern. By repetitive, I mean repetitive in a single application. Ex: multiple controllers, multiple models, etc. 95% of applications are going to create 1 Authlogic model and 1 controller for that model. If they are creating more than one, it is mostly likely for a highly unique situation where a generator would be of no use. Which leads me to my question:</p>
<p><strong>Why not just create your own personalized base application or template that you can start from when you need to start a new application?</strong></p>
<p>This is exactly why rails templates were created. They were created for this exact problem. A generator is never going to please everyone, and if it does, it would have a million options and be extremely complicated. Also, I don&#8217;t know about you, but I am extremely picky about my code. Even if my code and someone else&#8217;s code does the exact same thing, I want my code formatted a certain way. This is a big reason why I dislike restful_authentication. All of this code, that I do not like, gets inserted into my application. It just feels dirty. I&#8217;d much rather build my own authentication solution into a base app, that I like, and use that in my next application.</p>
<p>I just haven&#8217;t been convinced that creating a generator for Authlogic is a good use of my time. If you can convince me otherwise I&#8217;ll gladly do it. It&#8217;s not that I don&#8217;t want to spend the time, its that I truly feel a base app or a rails template is a better solution.</p>
<p>What do you think?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binarylogic.com/2009/04/17/authlogic-generators-all-of-the-cool-kids-are-doing-it/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Tutorial: Easily migrate from restful_authentication to Authlogic</title>
		<link>http://www.binarylogic.com/2008/11/23/tutorial-easily-migrate-from-restful_authentication-to-authlogic/</link>
		<comments>http://www.binarylogic.com/2008/11/23/tutorial-easily-migrate-from-restful_authentication-to-authlogic/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 22:46:00 +0000</pubDate>
		<dc:creator>benjohnson</dc:creator>
				<category><![CDATA[Authlogic]]></category>
		<category><![CDATA[migrate]]></category>
		<category><![CDATA[restful_authentication]]></category>
		<category><![CDATA[transition]]></category>

		<guid isPermaLink="false">0/2009/03/23/tutorial-easily-migrate-from-restful_authentication-to-authlogic</guid>
		<description><![CDATA[I&#8217;ve been getting a lot of emails asking the best way to migrate from restful_authentication. Where it gets complicated is in the password encryption methods. Authlogic and restful_authentication use different methods. You don&#8217;t want to change this method because it will break backwards compatibility with your current passwords, meaning no one will be able to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been getting a lot of emails asking the best way to migrate from restful_authentication. Where it gets complicated is in the password encryption methods. Authlogic and restful_authentication use different methods. You don&#8217;t want to change this method because it will break backwards compatibility with your current passwords, meaning no one will be able to log into their account. Fear not, because I did all of the hard work for you&#8230;</p>
<p><span id="more-253"></span></p>
<h2>Use the same password algorithm as restful_authentication</h2>
<pre class="ruby"># app/models/user.rb
class User &lt; ActiveRecord::Base
  acts_as_authentic do |c|
    c.act_like_restful_authentication = true
  end
end</pre>
<h2>Transition to one of Authlogic password algorithms</h2>
<p>The first thing you need to do is make sure your database field &#8220;crypted_password&#8221; and &#8220;salt&#8221; allow for the storage of at least 128 characters (assuming you are migrating to Sha512). restful_authentication uses Sha1 which is 40 characters. If you are limiting the size, you need to create a migration that looks similar to.</p>
<pre class="ruby">change_column :users, :crypted_password, :string, :limit =&gt; 128,
  :null =&gt; false, :default =&gt; ""

change_column :users, :salt, :string, :limit =&gt; 128,
  :null =&gt; false, :default =&gt; ""</pre>
<p>Now just tell acts_as_authentic what you are doing:</p>
<pre class="ruby"># app/models/user.rb
class User
  acts_as_authentic do |c|
    c.transition_from_restful_authentication = true
  end
end</pre>
<p>You could pass an optional argument to transition to any password algorithm you want. By default Authlogic uses the Sha512 algorithm, but let&#8217;s say you wanted to transition to the BCrypt algorithm. No problem</p>
<pre class="ruby"># app/models/user.rb
class User &lt; ActiveRecord::Base
  acts_as_authentic :transition_from_restful_authentication =&gt; true,
    :crypto_provider =&gt; Authlogic::CryptoProviders::BCrypt
end</pre>
<p>For more information on BCrypt <a href="http://www.binarylogic.com/2008/11/22/storing-nuclear-launch-codes-in-your-app-enter-bcrypt-for-authlogic">checkout my blog post about it</a>.</p>
<h2>What&#8217;s the difference?</h2>
<p>act_like_restful_authentication will not change a thing, your users passwords will remain in the same format. From your database&#8217;s perspective, it will be as if you are using restful_authentication.</p>
<p>transition_from_restful_authentication starts changing your users passwords using the Authlogic passwords system that you specify with the :crypto_provider option. How does it do this? It&#8217;s simple, every time a user successfully logs in and their password is encrypted with the restful_authentication algorithm it will update their password with the Authlogic algorithm. When a new account is created it will use the Authlogic algorithm. This allows your user base to slowly transition and allowing them to still be able to log in.</p>
<p>That&#8217;s it. I&#8217;m not going to go into the Authlogic set up because <a href="http://www.binarylogic.com/2008/11/3/tutorial-authlogic-basic-setup">I already have a tutorial on this</a>.</p>
<p>Let me know what you think or if you have any questions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binarylogic.com/2008/11/23/tutorial-easily-migrate-from-restful_authentication-to-authlogic/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Tutorial: Upgrade passwords easily with Authlogic</title>
		<link>http://www.binarylogic.com/2008/11/23/tutorial-upgrade-passwords-easily-with-authlogic/</link>
		<comments>http://www.binarylogic.com/2008/11/23/tutorial-upgrade-passwords-easily-with-authlogic/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 22:02:00 +0000</pubDate>
		<dc:creator>benjohnson</dc:creator>
				<category><![CDATA[Authlogic]]></category>
		<category><![CDATA[transition passwords]]></category>
		<category><![CDATA[upgrade passwords]]></category>

		<guid isPermaLink="false">0/2009/03/23/tutorial-upgrade-passwords-easily-with-authlogic</guid>
		<description><![CDATA[I released Authlogic 1.3.3 which has some handy options for migrating passwords to a new and improved algorithm. Without Authlogic this is somewhat of a pain in the ass, because there has to be a transition period in which your users can upgrade their passwords. You can&#8217;t just upgrade the algorithm because then no one [...]]]></description>
			<content:encoded><![CDATA[<p>I released Authlogic 1.3.3 which has some handy options for migrating passwords to a new and improved algorithm. Without Authlogic this is somewhat of a pain in the ass, because there has to be a transition period in which your users can upgrade their passwords. You can&#8217;t just upgrade the algorithm because then no one will be able to log in. Authlogic solves this problem and makes it dead simple:</p>
<p><span id="more-252"></span></p>
<h2>Migrating to another password algorithm within Authlogic</h2>
<p><a href="http://www.binarylogic.com/2008/11/22/storing-nuclear-launch-codes-in-your-app-enter-bcrypt-for-authlogic">I recently released BCrypt as an optional crypto provider for Authlogic</a>, let&#8217;s say you are using the default crypto provider Sha512 and want to start using BCrypt. No problem:</p>
<pre class="ruby"># app/models/user.rb
class User &lt; ActiveRecord::Base
  acts_as_authentic do |c|
    c.transition_from_crypto_providers = Authlogic::CryptoProviders::Sha512,
    c.crypto_provider = Authlogic::CryptoProviders::BCrypt
  end
end</pre>
<p>All of your users will be migrated to the new BCrypt method when they log in next or when a user creates a new account.</p>
<p>Let&#8217;s pretend a new algorithm came out called &#8220;CCrypt&#8221;, and its better than BCrypt, and you want to use it. You&#8217;re users are in the middle of transitioning from Sha512 to BCrypt. Oh no!</p>
<p>Not to worry, because Authlogic can transition your users from more than one algorithm. Just pass an array to :transition_from_crypto_provider:</p>
<pre class="ruby"># app/models/user.rb
class User &lt; ActiveRecord::Base
  acts_as_authentic do |c|
    c.transition_from_crypto_providers = [Authlogic::CryptoProviders::Sha512, Authlogic::CryptoProviders::BCrypt],
    c.crypto_provider = CCrypt
  end
end</pre>
<p>That&#8217;s it. You can specify as many as you want. When your users login or create a new account their passwords will be encrypted with the CCrypt algorithm.</p>
<h2>Migrating from any other password algorithm</h2>
<p>All that you need to do is create a crypto provider that represents how your passwords are encrypted. Believe it or not, it&#8217;s dead simple. Sometimes the easiest way to explain something is by using code example, so please checkout the Authlogic::CryptoProviders module and sub classes in the documentation. All that you need to do is create a class with a class level encrypt and matches? method:</p>
<pre class="ruby"># lib/my_awesome_crypto_provider.rb
class MyAwesomeCryptoProvider
  def self.encrypt(*tokens)
    # encrypt your password here
  end

  def self.matches?(crypted_password, *tokens)
    # return true if the tokens match the crypted_password
  end
end</pre>
<p>Transition to a new algorithm doesn&#8217;t get any easier than that.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binarylogic.com/2008/11/23/tutorial-upgrade-passwords-easily-with-authlogic/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Storing nuclear launch codes in your app? Enter BCrypt for Authlogic.</title>
		<link>http://www.binarylogic.com/2008/11/22/storing-nuclear-launch-codes-in-your-app-enter-bcrypt-for-authlogic/</link>
		<comments>http://www.binarylogic.com/2008/11/22/storing-nuclear-launch-codes-in-your-app-enter-bcrypt-for-authlogic/#comments</comments>
		<pubDate>Sat, 22 Nov 2008 18:43:00 +0000</pubDate>
		<dc:creator>benjohnson</dc:creator>
				<category><![CDATA[Authlogic]]></category>
		<category><![CDATA[bcrypt]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">0/2009/03/23/storing-nuclear-launch-codes-in-your-app-enter-bcrypt-for-authlogic</guid>
		<description><![CDATA[Today is Saturday, which is &#8220;fun day&#8221;, and there is nothing more fun that talking about encryption algorithms. So let&#8217;s get started&#8230;
Part of Authlogic&#8217;s responsibility to is to keep you on the cutting edge when it comes to security. Afterall, that is part of the reason you use Authlogic, so you don&#8221;t have to deal [...]]]></description>
			<content:encoded><![CDATA[<p>Today is Saturday, which is &#8220;fun day&#8221;, and there is nothing more fun that talking about encryption algorithms. So let&#8217;s get started&#8230;</p>
<p>Part of <a href="http://github.com/binarylogic/authlogic">Authlogic&#8217;s</a> responsibility to is to keep you on the cutting edge when it comes to security. Afterall, that is part of the reason you use Authlogic, so you don&#8221;t have to deal with it. Your app can use the latest and great security techniques just by updating the Authlogic gem.</p>
<p><span id="more-238"></span></p>
<p>That being said, today I released Authlogic 1.3.2. With this came a new optional crypto provider: BCrypt. According the to <a href="http://bcrypt.sourceforge.net/">BCrypt website</a>:</p>
<blockquote><p>&#8220;There are two kinds of cryptography in this world: cryptography that will stop your kid sister from reading your files, and cryptography that will stop major governments from reading your files.&#8221;</p></blockquote>
<p>My personal opinion is that the default Sha512 encryption that Authlogic uses is <em>plenty</em> secure, emphasis on plenty. Authlogic uses salted Sha512 with multiple stretches. Hell, the majority of apps use Sha1, because that&#8217;s what restful_authentication uses, and Sha1 is much less secure. I don&#8217;t want to link to these resources directly, but there are a number of resources available to perform reverse lookups on Sha1. I don&#8217;t want to paint the wrong picture here by saying Sha1 is insecure. It&#8217;s all in how you use it. As long as you are salting it and doing a number of stretches, which restful_authenticaton is doing, you are fine. But if you are storing extremely sensitive information in your app, such as nuclear launch codes, then you might consider something a little more secure.</p>
<h2>What makes BCrypt more secure?</h2>
<p>For one, BCrypt provides it&#8217;s own salting, then Authlogic provides salting as well. Double salting!</p>
<p>Secondly, when it comes to hashing algorithms, security mostly deals with the amount of time it takes to generate the hash. Take a dictionary attack on a Sha1 algorithm. A decent computer could fly through a list of every dictionary word in a relatively fast amount of time compared to BCrypt. Let me show you wish some benchmarks:</p>
<pre class="ruby">Benchmark.bm(18) do |x|
  x.report("BCrypt (cost = 10:") { 100.times { BCrypt::Password.create("mypass", :cost =&gt; 10) } }
  x.report("BCrypt (cost = 2:") { 100.times { BCrypt::Password.create("mypass", :cost =&gt; 2) } }
  x.report("Sha512:") { 100.times { Digest::SHA512.hexdigest("mypass") } }
  x.report("Sha1:") { 100.times { Digest::SHA1.hexdigest("mypass") } }
end

#                         user     system      total        real
# BCrypt (cost = 10): 10.780000   0.060000  10.840000 ( 11.100289)
# BCrypt (cost = 2):  0.180000   0.000000   0.180000 (  0.181914)
# Sha512:             0.000000   0.000000   0.000000 (  0.000829)
# Sha1:               0.000000   0.000000   0.000000 (  0.000395)</pre>
<p>That my friend is a huge difference. There is a trade off between security and performance. If you are willing to take the performance hit then go for it. Play with the :cost option to get that perfect balance between performance and security. By default the BCrypt library uses a cost of 10.</p>
<h2>Easily upgrade encryption and transition your users</h2>
<p>As I mentioned above, the cost can be adjusted. So let&#8217;s say 5 years from now a cost of 10 isn&#8217;t as effective as it used to be, because computers are now faster, things have advanced, etc. No problem, just bump the cost up to whatever is <em>now</em> suitable. Your old passwords will continue to work, while the new passwords will be much stronger.</p>
<p>Here&#8217;s why using a library like Authlogic is so nice. As your users start to log in, Authlogic will handle upgrading their passwords to the new and improved cost.</p>
<p>Now your app can move with the times and constantly stay on the cutting edge of security, and you don&#8217;t have to worry about breaking all of your users passwords.</p>
<p>This is a cool feature, but nothing to go crazy about. The average app will probably never need to upgrade their encryption algorithm. If your app is around long enough, maybe you will upgrade it once. Even then, it&#8217;s probably not necessary because of the salting and stretches. Regardless, Authlogic will assist you in your upgrade if you choose to do so.</p>
<p>Lastly, you can get this feature with any encryption algorithm, including Sha. Checkout the &#8220;Upgrading encryption methods&#8221; in the Authlogic README. It&#8217;s very simple.</p>
<h2>How do I use this?</h2>
<p>It&#8217;s simple:</p>
<pre>$ sudo gem install bcrypt-ruby</pre>
<p>Starting a new app?</p>
<pre class="ruby"># app/models/user.rb
class User &lt; ActiveRecord::Base
  acts_as_authentic do |c|
    crypto_provider = Authlogic::CryptoProviders::BCrypt
  end
end</pre>
<p>Looking to switch to BCrypt?:</p>
<pre class="ruby">class User &lt; ActiveRecord::Base
  acts_as_authentic do |c|
    c.crypto_provider = Authlogic::CryptoProviders::BCrypt
    c.transition_from_crypto_provider = Authlogic::CryptoProviders::Sha512
  end
end</pre>
<p>The transition_from_crypto_provider is whatever crypto provider you are currently using. Check out my blog posts about transitioning to another crypto provider:</p>
<ul>
<li><a href="http://www.binarylogic.com/2008/11/23/tutorial-upgrade-passwords-easily-with-authlogic">Upgrade passwords easily with Authlogic</a></li>
<li><a href="http://www.binarylogic.com/2008/11/23/tutorial-easily-migrate-from-restful_authentication-to-authlogic">Easily migrating from restful_authentication to Authlogic</a></li>
</ul>
<h2>What about [insert encryption method here]?</h2>
<p>Check out the Authlogic::CryptoProviders module and the subclasses within. You can add you own method just by creating a simple class and letting acts_as_authentic know about. Authlogic bundles some common methods as a convenience to you, there is nothing wrong with adding your own if you feel its necessary.</p>
<h2>Why isn&#8217;t this the default encryption method for Authlogic?</h2>
<p>I have heard of people having issues with the BCrypt library on windows. I have not used windows in years, so don&#8217;t take my word for it, but approach it with some caution. I decided to go with Sha512 since that is part of the ruby core and works wherever ruby can be installed.</p>
<p>Then again, using a library like bcrypt on windows is somewhat ironic. If you are very concerned with security I doubt you will be putting your app on windows. To me using BCrypt on Windows is like putting a state of the art lock on a cardboard box.</p>
<h2>Final thoughts</h2>
<p>The level of security your app provides is really up to you. Unless you are writing apps for the pentagon, the default Sha512 is fine. Regardless, Authlogic shouldn&#8217;t get in your way or make decisions for you, so if you feel BCrypt is necessary then go for it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binarylogic.com/2008/11/22/storing-nuclear-launch-codes-in-your-app-enter-bcrypt-for-authlogic/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Tutorial: Using OpenID with Authlogic</title>
		<link>http://www.binarylogic.com/2008/11/21/tutorial-using-openid-with-authlogic/</link>
		<comments>http://www.binarylogic.com/2008/11/21/tutorial-using-openid-with-authlogic/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 02:12:00 +0000</pubDate>
		<dc:creator>benjohnson</dc:creator>
				<category><![CDATA[Authlogic]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">0/2009/03/30/tutorial-using-openid-with-authlogic</guid>
		<description><![CDATA[Please note this tutorial is outdated and has been deleted, please see the official Authlogic OpenID addon, which makes OpenID integration extrmely easy. The content that used to be in this tutorial was for Authlogic 1.x and will not work properly with Authlogic 2.x.
]]></description>
			<content:encoded><![CDATA[<p><strong>Please note this tutorial is outdated and has been deleted, please see <a href="http://github.com/binarylogic/authlogic_openid">the official Authlogic OpenID addon</a>, which makes OpenID integration extrmely easy. The content that used to be in this tutorial was for Authlogic 1.x and will not work properly with Authlogic 2.x.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.binarylogic.com/2008/11/21/tutorial-using-openid-with-authlogic/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Tutorial: Reset passwords with Authlogic the RESTful way</title>
		<link>http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic/</link>
		<comments>http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic/#comments</comments>
		<pubDate>Sun, 16 Nov 2008 15:19:00 +0000</pubDate>
		<dc:creator>benjohnson</dc:creator>
				<category><![CDATA[Authlogic]]></category>
		<category><![CDATA[passwords]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">0/2009/03/23/tutorial-reset-passwords-with-authlogic</guid>
		<description><![CDATA[I&#8217;ve been getting emails asking me how to reset passwords with Authlogic, or how to confirm accounts. In this tutorial I&#8217;ll cover resetting passwords, since it is more complex, but after reading this tutorial there is no reason why you couldn&#8217;t set up account confirmation as well. In fact, my next tutorial will cover just [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been getting emails asking me how to reset passwords with <a href="http://github.com/binarylogic/authlogic">Authlogic</a>, or how to confirm accounts. In this tutorial I&#8217;ll cover resetting passwords, since it is more complex, but after reading this tutorial there is no reason why you couldn&#8217;t set up account confirmation as well. In fact, my next tutorial will cover just that.</p>
<h2>What am I about to read?</h2>
<p>You are going to read a tutorial on how to reset passwords the RESTful way. I am going to pick up where I left off on the <a href="http://www.binarylogic.com/2008/11/3/tutorial-authlogic-basic-setup">Authlogic basic setup tutorial</a>, so if you have not read that I highly recommend doing so.</p>
<p>Want to see it in action before you start? Check it out for yourself:</p>
<h3><a href="http://authlogic_example.binarylogic.com">A live example of this tutorial</a></h3>
<p>Before we begin, let me walk you through the basic process of resetting a password as I see it:</p>
<p><span id="more-133"></span></p>
<ol>
<li>A user requests a password reset</li>
<li>An email is sent to them with a link to reset their password</li>
<li>The user verifies their identity be using the link we emailed them</li>
<li>They are presented with a basic form to change their password</li>
<li>After they change their password we log them in, redirect them to their account, and expire the URL we just sent them</li>
</ol>
<p>That seems pretty simple, right? So let&#8217;s get started&#8230;</p>
<h2>Helpful links</h2>
<p>Before we start I want give you some helpful / related links:</p>
<ul>
<li><a href="http://www.binarylogic.com/2008/11/3/tutorial-authlogic-basic-setup">Tutorial: Authlogic basic setup</a></li>
<li><a href="http://authlogic_example.binarylogic.com/">Live example of the this tutorial</a></li>
<li><a href="http://github.com/binarylogic/authlogic_example/tree/with-password-resets">Source code of this tutorial</a></li>
<li><a href="http://github.com/binarylogic/authlogic">Authlogic repository</a></li>
<li><a href="http://authlogic.rubyforge.org/">Authlogic documentation</a></li>
</ul>
<h2>1. Add in the reset_password_token and email fields</h2>
<p>I am going to pick up from the <a href="http://www.binarylogic.com/2008/11/3/tutorial-authlogic-basic-setup">Authlogic basic setup tutorial</a>, so I am assuming you are familiar with Authlogic and the basic setup.</p>
<p>With this tutorial I am introducing a new field in your database called <strong>perishable_token</strong>. Authlogic will take care of maintaining this for you. Here is how:</p>
<ol>
<li>The token gets set to a unique value before validation, which constantly changes the token. The value is a &#8220;friendly&#8221; value, something like: 4LiXF7FiGUppIPubBPey, not as long or as hardcore as a Sha512 hash, so it doesn&#8217;t cause problems when emailed or copying and pasting into a browser.</li>
<li>After a session is successfully saved (aka logged in) the the token will be reset. This makes the email we sent them before no longer usable.</li>
</ol>
<p>Generate your migration:</p>
<pre>$ script/generate migration add_users_password_reset_fields</pre>
<p>Now update the migration:</p>
<pre name="code" class="ruby">
class AddUsersPasswordResetFields &lt; ActiveRecord::Migration
def self.up
add_column :users, :perishable_token, :string, :default =&gt; "", :null =&gt; false
add_column :users, :email, :string, :default =&gt; "", :null =&gt; false

add_index :users, :perishable_token
add_index :users, :email
end

def self.down
remove_column :users, :perishable_token
remove_column :users, :email
end
end
</pre>
<p>Migrate your database:</p>
<pre>$ rake db:migrate</pre>
<p>When adding the email field Authlogic will notice this and validate it for you, making sure the email is unique and a valid email address. If you wish to disable this just pass the :validate_email_field =&gt; false option to acts_as_authentic. You can also have it ignore the email field all together by passing the :email_field =&gt; nil option.</p>
<h2>2. Let users request a password reset</h2>
<p>We need to know if users lost their password, why not create another resource for this?</p>
<pre>$ script/generate controller password_resets</pre>
<p>Let&#8217;s fill out this controller with some actions (I will explain them below):</p>
<p>Now update your routes:</p>
<pre name="code" class="ruby">
# app/controllers/password_resets_controller.rb
class PasswordResetsController &lt; ApplicationController
def new
render
end

def create
@user = User.find_by_email(params[:email])
if @user
@user.deliver_password_reset_instructions!
flash[:notice] = "Instructions to reset your password have been emailed to you. " +
"Please check your email."
redirect_to root_url
else
flash[:notice] = "No user was found with that email address"
render :action =&gt; :new
end
end
end
</pre>
<p><strong>What did I just do?</strong></p>
<p>The deliver_password_reset_instructions! is a method I added, you can call it whatever you want. All that it does is reset the password reset token and send an email.</p>
<p>Here is what I did in my own application:</p>
<pre name="code" class="ruby">
# app/models/user.rb
class User &lt; ActiveRecord::Base
def deliver_password_reset_instructions!
reset_perishable_token!
Notifier.deliver_password_reset_instructions(self)
end
end
</pre>
<p>The reset_perishable_token! is a handy method Authlogic gives you. It basically resets the field to a unique &#8220;friendly&#8221; token and then saves the record.</p>
<p>My Notifier action looks like this:</p>
<pre name="code" class="ruby">
# app/models/notifier.rb
class Notifier &lt; ActionMailer::Base
default_url_options[:host] = "authlogic_example.binarylogic.com"

def password_reset_instructions(user)
subject       "Password Reset Instructions"
from          "Binary Logic Notifier "
recipients    user.email
sent_on       Time.now
body          :edit_password_reset_url =&gt; edit_password_reset_url(user.perishable_token)
end
end
</pre>
<p>Then the email looks like:</p>
<pre name="code" class="ruby">
# app/views/notifier/password_reset_instructions.erb
A request to reset your password has been made.
If you did not make this request, simply ignore this email.
If you did make this request just click the link below:

If the above URL does not work try copying and pasting it into your browser.
If you continue to have problem please feel free to contact us.
</pre>
<p>You can do the above any way you want. I actually recommend creating a text and html version of this email, but for the sake of brevity I only included the text version.</p>
<h2>3. Let users reset their password</h2>
<p>Once they get that email and click the link in it, it needs to take them somewhere. So let&#8217;s add some methods to our PasswordResetsController:</p>
<pre name="code" class="ruby">
# app/controllers/password_resets_controller.rb
before_filter :load_user_using_perishable_token, :only =&gt; [:edit, :update]

def edit
render
end

def update
@user.password = params[:user][:password]
@user.password_confirmation = params[:user][: password_confirmation]
if @user.save
flash[:notice] = "Password successfully updated"
redirect_to account_url
else
render :action =&gt; :edit
end
end

private
def load_user_using_perishable_token
@user = User.find_using_perishable_token(params[:id])
unless @user
flash[:notice] = "We're sorry, but we could not locate your account. " +
"If you are having issues try copying and pasting the URL " +
"from your email into your browser or restarting the " +
"reset password process."
redirect_to root_url
end
end
</pre>
<p><strong>What did I just do?</strong></p>
<ol>
<li>You really don&#8217;t need to add the edit method because its a blank method, the before_filter takes care of everything we need to do there. There is only a view for this method.</li>
<li>The update method is nice, because if the user is successfully saved, Authlogic will automatically log them in, keeping your PasswordResetsController focused on resetting passwords, not sessions.</li>
<li>The load_user_using_perishable_token has a unique method: find_using_perishable_token. This is a special method that Authlogic gives you. Here is what it does for extra security:
<ol>
<li>Ignores blank tokens</li>
<li>Only finds records that match the token and have an updated_at (if present) value that is not older than 10 minutes. This way, if someone gets the data in your database any valid perishable tokens will expire in 10 minutes. Chances are they will expire quicker because the token is changing during user activity as well.</li>
</ol>
</li>
</ol>
<h2>4. Restrict access</h2>
<p>Now we just need to make sure the user is logged out when accessing these methods. Modify your before filters in your PasswordResetsController to look like:</p>
<pre name="code" class="ruby">
before_filter :require_no_user
</pre>
<h2>Where are the views?</h2>
<p>Instead of cluttering up this tutorial with a bunch of basic views, I left them out. There is nothing crazy going on in the views, nor do I really need to explain anything. If you noticed in the helpful links section I have a live example of this tutorial.</p>
<p><a href="http://github.com/binarylogic/authlogic_example/tree/with-password-resets/app/views">Here is a direct link to the users views source code, you can copy the views over from here</a></p>
<h2>Why not reset passwords this way&#8230;?</h2>
<p>If you care, here are my thoughts behind this tutorial and ultimately why I recommend resetting passwords this way&#8230;</p>
<p>My goal with Authlogic was to stay away from generating code and give you the proper tools so that you could easily and effectively write the code yourself. If you noticed, in this tutorial, all that we really did was add a simple PasswordResetsController. Most of this tutorial was explaining what was going on, so you could understand what you were doing. I can&#8217;t write that controller for you, because it is application specific. I want to keep the authentication logic in Authlogic and your application logic in your application. The tutorial above produces simpler and cleaner code than a generator. The most important part is that you understand what is going on and it works the way you want. I am basically laying out tools for you to use and explaining them. You get to use them how you wish. There is no &#8220;Surprise! Here are hundreds of lines of code, hope you like it&#8221;. If you want to change passwords a different way, go for it, you now know how Authlogic can assist you in your journey to resetting passwords.</p>
<p>Lastly, I know there are a few other common ways to reset passwords, so I will address those and why I decided against them:</p>
<ol>
<li><strong>Changing / randomizing the password during the first step and then emailing them their new password</strong><br />
You should NEVER change anyone&#8217;s password until they have proven they are that user. What if Billy 13 year old starts typing in random logins and resetting peoples passwords? Those people aren&#8217;t going to be happy.</li>
<li><strong>Using an already existing token that is not unique or perishable</strong><br />
A lot of people are tempted to use the remember_token, single_access_token, or even the crypted_password for authenticating the user for a password change. There is a reason we have all of these and none of these should be used for resetting password. What if Billy 13 year old gets ahold of any of these, he will have full access to resetting that user&#8217;s password, and then have full access to their account. If for some reason he gets any of these things, your users should still be protected, which is why we need a unique and perishable token.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic/feed/</wfw:commentRss>
		<slash:comments>42</slash:comments>
		</item>
		<item>
		<title>Authlogic shares the love, merb support added</title>
		<link>http://www.binarylogic.com/2008/11/05/authlogic-shares-the-love-merb-support-added/</link>
		<comments>http://www.binarylogic.com/2008/11/05/authlogic-shares-the-love-merb-support-added/#comments</comments>
		<pubDate>Wed, 05 Nov 2008 19:06:00 +0000</pubDate>
		<dc:creator>benjohnson</dc:creator>
				<category><![CDATA[Authlogic]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">0/2009/03/23/authlogic-shares-the-love-merb-support-added</guid>
		<description><![CDATA[Rails doesn&#8217;t have to hog all of the Authlogic love, it&#8217;s time to start sharing. So I decided to send a little love to the merb peeps and add in a merb adapter. Just install the Authlogic gem and include it as a dependency and you are good to go. Authentication in your app is [...]]]></description>
			<content:encoded><![CDATA[<p>Rails doesn&#8217;t have to hog all of the <a href="http://github.com/binarylogic/authlogic">Authlogic</a> love, it&#8217;s time to start sharing. So I decided to send a little love to the merb peeps and add in a merb adapter. Just install the <a href="http://github.com/binarylogic/authlogic">Authlogic</a> gem and include it as a dependency and you are good to go. Authentication in your app is as easy as setting up a resource for a model.</p>
<p>I think this is just the beginning though, here are my thoughts&#8230;.</p>
<p>            <span id="more-163"></span></p>
<h2>The Big Picture</h2>
<p>Thanks to things like <a href="http://rack.rubyforge.org/">Rack</a>, the MVC design pattern, and ActiveRecord / DataMapper, all of these frameworks look very similar. They all have a similar pattern, which is the inherent nature of the MVC design pattern. So I decided to take advantage of this with Authlogic. Any specific framework implementation is extracted out into an adapter. Similar to how ActiveRecord has an adapter for each database type, except the Authlogic adapters are much simpler.</p>
<p>Probably the main reason these adapters are so simple / similar is because of Rack. Thanks to Rack, there is a request standard across all of these frameworks. &#8220;But Ben, why not skip all of this nonsense and implement this right into Rack?&#8221;. The reason I didn&#8217;t go right into Rack is&#8230;</p>
<ol>
<li>Not every &#8220;Rack compatible&#8221; framework uses the Rack libraries. After digging through the rails internals I found that the RackRequest class extends AbstractRequest, which has nothing to do with Rack. Lastly, older versions of rails aren&#8217;t rack compatible.</li>
<li>I need to hook into the controller anyways with a before_filter</li>
<li>With my implementation you get the best of both worlds. I designed the AbstractAdapter to conform to the rack standards, and any framework specific implementation can subclass this and do it&#8217;s magic.</li>
</ol>
<p>So what&#8217;s the big picture here? The big picture is that there is no reason Authlogic can&#8217;t be an authentication solution for virtually any ruby framework out there. Why reinvent the wheel for every framework?</p>
<h2>What about framework X?</h2>
<p>Since writing adapters for rails and merb was so simple, why not keep going? Here are a few frameworks I plan to write an adapter for:</p>
<ol>
<li><a href="http://www.mackframework.com/">Mack</a></li>
<li><a href="http://ramaze.net/">Ramaze</a></li>
<li><a href="http://sinatra.rubyforge.org/">Sinatra</a></li>
</ol>
<p>If you are feeling generous and want to write an adapter for a framework other than rails or merb, please do so. Let me know about it and I will add it into the source.</p>
<h2>Final thoughts</h2>
<p>Authlogic loves you regardless of your framework</p>
]]></content:encoded>
			<wfw:commentRss>http://www.binarylogic.com/2008/11/05/authlogic-shares-the-love-merb-support-added/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tutorial: Authlogic Basic Setup</title>
		<link>http://www.binarylogic.com/2008/11/03/tutorial-authlogic-basic-setup/</link>
		<comments>http://www.binarylogic.com/2008/11/03/tutorial-authlogic-basic-setup/#comments</comments>
		<pubDate>Mon, 03 Nov 2008 12:48:00 +0000</pubDate>
		<dc:creator>benjohnson</dc:creator>
				<category><![CDATA[Authlogic]]></category>
		<category><![CDATA[setup tutorial]]></category>

		<guid isPermaLink="false">0/2009/04/03/tutorial-authlogic-basic-setup</guid>
		<description><![CDATA[Please note this tutorial has been moved to the README in the authlogic_example respository. This tutorial is stored with the example app incase you are more of a hands on learner, you can play around with the resulting code.
]]></description>
			<content:encoded><![CDATA[<p><strong>Please note this tutorial has been moved to the <a href="http://github.com/binarylogic/authlogic_example/tree/master">README in the authlogic_example respository</a>. This tutorial is stored with the example app incase you are more of a hands on learner, you can play around with the resulting code.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.binarylogic.com/2008/11/03/tutorial-authlogic-basic-setup/feed/</wfw:commentRss>
		<slash:comments>65</slash:comments>
		</item>
		<item>
		<title>Authlogic released! Rails authentication done right.</title>
		<link>http://www.binarylogic.com/2008/10/25/authlogic-released-rails-authentication-done-right/</link>
		<comments>http://www.binarylogic.com/2008/10/25/authlogic-released-rails-authentication-done-right/#comments</comments>
		<pubDate>Sat, 25 Oct 2008 12:24:00 +0000</pubDate>
		<dc:creator>benjohnson</dc:creator>
				<category><![CDATA[Authlogic]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[restful]]></category>
		<category><![CDATA[session]]></category>

		<guid isPermaLink="false">0/2009/03/23/authlogic-released-rails-authentication-done-right</guid>
		<description><![CDATA[The last thing we need is another authentication solution for rails, right? That&#8217;s what I thought until I tried out some of the current solutions. None of them felt right. They were either too complicated, bloated, littered my application with tons of code, or were just confusing. This is not the simple / elegant rails [...]]]></description>
			<content:encoded><![CDATA[<p>The last thing we need is another authentication solution for rails, right? That&#8217;s what I thought until I tried out some of the current solutions. None of them felt right. They were either too complicated, bloated, littered my application with tons of code, or were just confusing. This is not the simple / elegant rails we all fell in love with. We need a &#8220;rails like&#8221; authentication solution. Authlogic is my attempt to satisfy that need&#8230;</p>
<p>What if you could have authentication up and running in minutes without having to run a generator? All because it&#8217;s simple, like everything else in rails.</p>
<p>What if creating a user session could be as simple as&#8230;</p>
<pre class="cobalt">
<span class="Support">UserSession</span><span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">create</span></span><span class="Punctuation">(</span>params<span class="Punctuation">[</span><span class="Constant"><span class="Punctuation">:</span>user</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
</pre>
<p>What if your user sessions controller could look just like your other controllers&#8230;</p>
<p>            <span id="more-103"></span></p>
<pre class="cobalt">
<span class="Keyword">class</span> <span class="Entity">UserSessionsController<span class="EntityInheritedClass"> <span class="Punctuation">&lt;</span> ApplicationController</span></span>
  <span class="Keyword">def</span> <span class="Entity">new</span>
    <span class="Variable"><span class="Punctuation">@</span>user_session</span> <span class="Keyword">=</span> <span class="Support">UserSession</span><span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">new</span></span>
  <span class="Keyword">end</span>

  <span class="Keyword">def</span> <span class="Entity">create</span>
    <span class="Variable"><span class="Punctuation">@</span>user_session</span> <span class="Keyword">=</span> <span class="Support">UserSession</span><span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">new</span></span><span class="Punctuation">(</span>params<span class="Punctuation">[</span><span class="Constant"><span class="Punctuation">:</span>user_session</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
    <span class="Keyword">if</span> <span class="Variable"><span class="Punctuation">@</span>user_session</span><span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">create</span></span>
      redirect_to account_url
    <span class="Keyword">else</span>
      render <span class="Constant"><span class="Punctuation">:</span>action</span> <span class="Punctuation">=&gt;</span> <span class="Constant"><span class="Punctuation">:</span>new</span>
    <span class="Keyword">end</span>
  <span class="Keyword">end</span>

  <span class="Keyword">def</span> <span class="Entity">destroy</span>
    current_user_session<span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">destroy</span></span>
  <span class="Keyword">end</span>
<span class="Keyword">end</span>
</pre>
<p>Look familiar? If you didn&#8217;t know any better, you would think UserSession was an ActiveRecord model. I think that&#8217;s pretty cool. Why is that cool? Because it fits nicely into the RESTful development pattern and its a style we all know and love. Wouldn&#8217;t this be cool too&#8230;</p>
<pre class="cobalt">
<span class="Keyword">&lt;</span><span class="Keyword">%=</span> error_messages_for <span class="String"><span class="Punctuation">&quot;</span>user_session<span class="Punctuation">&quot;</span></span> <span class="String"><span class="Punctuation">%&gt;</span></span>
<span class="String">&lt;% form_for @user_session do |f| %<span class="Punctuation">&gt;</span></span>
  <span class="Keyword">&lt;</span><span class="Keyword">%=</span> f<span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">label</span></span> <span class="Constant"><span class="Punctuation">:</span>login</span> <span class="String"><span class="Punctuation">%&gt;</span>&lt;br /<span class="Punctuation">&gt;</span></span>
  <span class="Keyword">&lt;</span><span class="Keyword">%=</span> f<span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">text_field</span></span> <span class="Constant"><span class="Punctuation">:</span>login</span> <span class="String"><span class="Punctuation">%&gt;</span>&lt;br /<span class="Punctuation">&gt;</span></span>
  <span class="Keyword">&lt;</span>br <span class="Keyword">/</span><span class="Keyword">&gt;</span>
  <span class="Keyword">&lt;</span><span class="Keyword">%=</span> f<span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">label</span></span> <span class="Constant"><span class="Punctuation">:</span>password</span> <span class="String"><span class="Punctuation">%&gt;</span>&lt;br /<span class="Punctuation">&gt;</span></span>
  <span class="Keyword">&lt;</span><span class="Keyword">%=</span> f<span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">password_field</span></span> <span class="Constant"><span class="Punctuation">:</span>password</span> <span class="String"><span class="Punctuation">%&gt;</span>&lt;br /<span class="Punctuation">&gt;</span></span>
  <span class="Keyword">&lt;</span>br <span class="Keyword">/</span><span class="Keyword">&gt;</span>
  <span class="Keyword">&lt;</span><span class="Keyword">%=</span> f<span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">submit</span></span> <span class="String"><span class="Punctuation">&quot;</span>Login<span class="Punctuation">&quot;</span></span> <span class="String"><span class="Punctuation">%&gt;</span></span>
<span class="String">&lt;% end %<span class="Punctuation">&gt;</span></span>
</pre>
<p>Or what about persisting the session&#8230;</p>
<pre class="cobalt">
<span class="Keyword">class</span> <span class="Entity">ApplicationController</span>
  helper_method <span class="Constant"><span class="Punctuation">:</span>current_user_session</span><span class="Punctuation">,</span> <span class="Constant"><span class="Punctuation">:</span>current_user</span>

  <span class="Keyword">protected</span>
    <span class="Keyword">def</span> <span class="Entity">current_user_session</span>
      <span class="Keyword">return</span> <span class="Variable"><span class="Punctuation">@</span>current_user_session</span> <span class="Keyword">if</span> <span class="Keyword">defined?</span><span class="Punctuation">(</span><span class="Variable"><span class="Punctuation">@</span>current_user_session</span><span class="Punctuation">)</span>
      <span class="Variable"><span class="Punctuation">@</span>current_user_session</span> <span class="Keyword">=</span> <span class="Support">UserSession</span><span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">find</span></span>
    <span class="Keyword">end</span>

    <span class="Keyword">def</span> <span class="Entity">current_user</span>
      <span class="Keyword">return</span> <span class="Variable"><span class="Punctuation">@</span>current_user</span> <span class="Keyword">if</span> <span class="Keyword">defined?</span><span class="Punctuation">(</span><span class="Variable"><span class="Punctuation">@</span>current_user</span><span class="Punctuation">)</span>
      <span class="Variable"><span class="Punctuation">@</span>current_user</span> <span class="Keyword">=</span> current_user_session <span class="Keyword">&amp;&amp;</span> current_user_session<span class="FunctionCall"><span class="Punctuation">.</span><span class="Entity">user</span></span>
    <span class="Keyword">end</span>
<span class="Keyword">end</span>
</pre>
<p>Authlogic makes this a reality.</p>
<h2>Reclaim your UsersController</h2>
<p>This is one of my favorite features that I think its pretty cool. It&#8217;s things like this that make a library great and let you know you are on the right track.</p>
<p>Just to clear up any confusion, Authlogic does not store the plain id in the session. It stores a token. This token changes with the password, this way stale sessions can not be persisted.</p>
<p>That being said..What if a user changes their password? You have to re-log them in with the new password, recreate the session, etc, pain in the ass. Or what if a user creates a new user account? You have to do the same thing. Here&#8217;s an even better one: what if a user is in the admin area and changes his own password? There might even be another place passwords can change. It shouldn&#8217;t matter, your code should be written in a way where you don&#8217;t have to remember to do this.</p>
<p>Instead of updating sessions all over the place, doesn&#8217;t it make sense to do this at a lower level? Like the User model? You&#8217;re saying &#8220;but Ben, models can&#8217;t mess around with sessions and cookies&#8221;. True&#8230;but Authlogic can, and you can access Authlogic just like a model. I know in most situations it&#8217;s not good practice to do this but I view this in the same class as sweepers, and feel like it actually is good practice here. User sessions are directly tied to users, they should be connected on the model level.</p>
<p>Fear not, because the acts_as_authentic method you call in your model takes care of this for you, by adding an after_create and after_update callback to automatically keep the session up to date. You don&#8217;t have to worry about it anymore. Don&#8217;t even think about it. Let your UsersController deal with users, not users <em>AND</em> sessions. <em>ANYTIME</em> the user changes his password in <em>ANY</em> way, his session will be updated.</p>
<p>Here is basically what is done&#8230;</p>
<pre class="cobalt">
<span class="Keyword">class</span> <span class="Entity">User<span class="EntityInheritedClass"> <span class="Punctuation">&lt;</span> ActiveRecord::Base</span></span>
  after_save <span class="Constant"><span class="Punctuation">:</span>maintain_sessions!</span>

  <span class="Keyword">private</span>
    <span class="Keyword">def</span> <span class="Entity">create_sessions!</span>
<span class="Comment">      <span class="Punctuation">#</span> create a new UserSession if they are not logged in</span>
    <span class="Keyword">end</span>

    <span class="Keyword">def</span> <span class="Entity">maintain_sessions!</span>
<span class="Comment">      <span class="Punctuation">#</span> If we aren't logged in at all and the password was changed, go ahead and log the user in</span>
<span class="Comment">      <span class="Punctuation">#</span> If we are logged in and the password has change, update the sessions</span>
    <span class="Keyword">end</span>
<span class="Keyword">end</span>
</pre>
<p>Obviously there is a little more to it than this, but hopefully this clarifies any confusion.</p>
<p>When things come together like this I think its a sign that you are doing something right. Put that in your pipe and smoke it!</p>
<h2>Authlogic arouses me</h2>
<p>That&#8217;s great, here are some resources:</p>
<ul>
<li><strong>Repository:</strong> <a href="http://github.com/binarylogic/authlogic">http://github.com/binarylogic/authlogic</a></li>
<li><strong>Documentation:</strong> <a href="http://authlogic.rubyforge.org/">http://authlogic.rubyforge.org/</a></li>
<li><strong>Tutorial:</strong> coming soon&#8230;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.binarylogic.com/2008/10/25/authlogic-released-rails-authentication-done-right/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
	</channel>
</rss>
