authlogic 0.10.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of authlogic might be problematic. Click here for more details.

Files changed (102) hide show
  1. data/CHANGELOG.rdoc +47 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Manifest +100 -0
  4. data/README.rdoc +292 -0
  5. data/Rakefile +15 -0
  6. data/authlogic.gemspec +38 -0
  7. data/init.rb +1 -0
  8. data/lib/authlogic.rb +25 -0
  9. data/lib/authlogic/active_record/acts_as_authentic.rb +265 -0
  10. data/lib/authlogic/active_record/authenticates_many.rb +19 -0
  11. data/lib/authlogic/active_record/scoped_session.rb +28 -0
  12. data/lib/authlogic/controller_adapters/abstract_adapter.rb +25 -0
  13. data/lib/authlogic/controller_adapters/rails_adapter.rb +39 -0
  14. data/lib/authlogic/session/active_record_trickery.rb +26 -0
  15. data/lib/authlogic/session/base.rb +510 -0
  16. data/lib/authlogic/session/callbacks.rb +56 -0
  17. data/lib/authlogic/session/config.rb +237 -0
  18. data/lib/authlogic/session/errors.rb +18 -0
  19. data/lib/authlogic/sha512_crypto_provider.rb +18 -0
  20. data/lib/authlogic/version.rb +56 -0
  21. data/test_app/README +256 -0
  22. data/test_app/Rakefile +10 -0
  23. data/test_app/app/controllers/application.rb +72 -0
  24. data/test_app/app/controllers/companies_controller.rb +2 -0
  25. data/test_app/app/controllers/user_sessions_controller.rb +25 -0
  26. data/test_app/app/controllers/users_controller.rb +61 -0
  27. data/test_app/app/helpers/application_helper.rb +3 -0
  28. data/test_app/app/helpers/companies_helper.rb +2 -0
  29. data/test_app/app/helpers/user_sessions_helper.rb +2 -0
  30. data/test_app/app/helpers/users_helper.rb +2 -0
  31. data/test_app/app/models/company.rb +4 -0
  32. data/test_app/app/models/project.rb +3 -0
  33. data/test_app/app/models/user.rb +5 -0
  34. data/test_app/app/models/user_session.rb +3 -0
  35. data/test_app/app/views/layouts/application.html.erb +27 -0
  36. data/test_app/app/views/user_sessions/new.html.erb +15 -0
  37. data/test_app/app/views/users/_form.erb +15 -0
  38. data/test_app/app/views/users/edit.html.erb +8 -0
  39. data/test_app/app/views/users/new.html.erb +8 -0
  40. data/test_app/app/views/users/show.html.erb +29 -0
  41. data/test_app/config/boot.rb +109 -0
  42. data/test_app/config/database.yml +19 -0
  43. data/test_app/config/environment.rb +69 -0
  44. data/test_app/config/environments/development.rb +17 -0
  45. data/test_app/config/environments/production.rb +22 -0
  46. data/test_app/config/environments/test.rb +22 -0
  47. data/test_app/config/initializers/inflections.rb +10 -0
  48. data/test_app/config/initializers/mime_types.rb +5 -0
  49. data/test_app/config/initializers/new_rails_defaults.rb +17 -0
  50. data/test_app/config/routes.rb +11 -0
  51. data/test_app/db/development.sqlite3 +0 -0
  52. data/test_app/db/migrate/20081023040052_create_users.rb +20 -0
  53. data/test_app/db/migrate/20081103003828_create_companies.rb +14 -0
  54. data/test_app/db/migrate/20081103003834_create_projects.rb +18 -0
  55. data/test_app/db/schema.rb +46 -0
  56. data/test_app/db/test.sqlite3 +0 -0
  57. data/test_app/doc/README_FOR_APP +2 -0
  58. data/test_app/public/404.html +30 -0
  59. data/test_app/public/422.html +30 -0
  60. data/test_app/public/500.html +30 -0
  61. data/test_app/public/dispatch.cgi +10 -0
  62. data/test_app/public/dispatch.fcgi +24 -0
  63. data/test_app/public/dispatch.rb +10 -0
  64. data/test_app/public/favicon.ico +0 -0
  65. data/test_app/public/images/rails.png +0 -0
  66. data/test_app/public/javascripts/application.js +2 -0
  67. data/test_app/public/javascripts/controls.js +963 -0
  68. data/test_app/public/javascripts/dragdrop.js +972 -0
  69. data/test_app/public/javascripts/effects.js +1120 -0
  70. data/test_app/public/javascripts/prototype.js +4225 -0
  71. data/test_app/public/robots.txt +5 -0
  72. data/test_app/public/stylesheets/scaffold.css +62 -0
  73. data/test_app/script/about +4 -0
  74. data/test_app/script/console +3 -0
  75. data/test_app/script/dbconsole +3 -0
  76. data/test_app/script/destroy +3 -0
  77. data/test_app/script/generate +3 -0
  78. data/test_app/script/performance/benchmarker +3 -0
  79. data/test_app/script/performance/profiler +3 -0
  80. data/test_app/script/performance/request +3 -0
  81. data/test_app/script/plugin +3 -0
  82. data/test_app/script/process/inspector +3 -0
  83. data/test_app/script/process/reaper +3 -0
  84. data/test_app/script/process/spawner +3 -0
  85. data/test_app/script/runner +3 -0
  86. data/test_app/script/server +3 -0
  87. data/test_app/test/fixtures/companies.yml +7 -0
  88. data/test_app/test/fixtures/projects.yml +4 -0
  89. data/test_app/test/fixtures/users.yml +21 -0
  90. data/test_app/test/functional/companies_controller_test.rb +8 -0
  91. data/test_app/test/functional/user_sessions_controller_test.rb +36 -0
  92. data/test_app/test/functional/users_controller_test.rb +8 -0
  93. data/test_app/test/integration/company_user_session_stories_test.rb +46 -0
  94. data/test_app/test/integration/user_sesion_stories_test.rb +105 -0
  95. data/test_app/test/integration/user_session_config_test.rb +24 -0
  96. data/test_app/test/integration/user_session_test.rb +161 -0
  97. data/test_app/test/test_helper.rb +81 -0
  98. data/test_app/test/unit/account_test.rb +8 -0
  99. data/test_app/test/unit/company_test.rb +8 -0
  100. data/test_app/test/unit/project_test.rb +8 -0
  101. data/test_app/test/unit/user_test.rb +80 -0
  102. metadata +201 -0
@@ -0,0 +1,47 @@
1
+ == 0.10.4 released 2008-10-31
2
+
3
+ * Changed configuration to use inheritable attributes
4
+ * Cleaned up requires to be in their proper files
5
+ * Added in scope support.
6
+
7
+ == 0.10.3 released 2008-10-31
8
+
9
+ * Instead of raising an error when extra fields are passed in credentials=, just ignore them.
10
+ * Added remember_me config option to set the default value.
11
+ * Only call credential methods if an argument was passed.
12
+ * More unit tests
13
+ * Hardened automatic session updating. Also automatically log the user in if they change their password when logged out.
14
+
15
+ == 0.10.2 released 2008-10-24
16
+
17
+ * Added in stretches to the default Sha512 encryption algorithm.
18
+ * Use column_names instead of columns when determining if a column is present.
19
+ * Improved validation callbacks. after_validation should only be run if valid? = true. Also clear errors before the "before_validation" callback.
20
+
21
+ == 0.10.1 released 2008-10-24
22
+
23
+ * Sessions now store the "remember token" instead of the id. This is much safer and guarantees all "sessions" that are logged in are logged in with a valid password. This way stale sessions can't be persisted.
24
+ * Bumped security to Sha512 from Sha256.
25
+ * Remove attr_protected call in acts_as_authentic
26
+ * protected_password should use pasword_field configuration value
27
+ * changed magic state "inactive" to "active"
28
+
29
+ == 0.10.0 released 2008-10-24
30
+
31
+ * Do not allow instantiation if the session has not been activated with a controller object. Just like ActiveRecord won't let you do anything without a DB connection.
32
+ * Abstracted controller implementation to allow for rails, merb, etc adapters. So this is not confined to the rails framework.
33
+ * Removed create and update methods and added save, like ActiveRecord.
34
+ * after_validation should be able to change the result if it adds errors on callbacks.
35
+ * Completed tests.
36
+
37
+ == 0.9.1 released 2008-10-24
38
+
39
+ * Changed scope to id. Makes more sense to call it an id and fits better with the ActiveRecord model.
40
+ * Removed saving_from_session flag, apparently it is not needed.
41
+ * Fixed updating sessions to make more sense and be stricter.
42
+ * change last_click_at to last_request_at
43
+ * Only run "after" callbacks if the result is successful.
44
+
45
+ == 0.9.0 released 2008-10-24
46
+
47
+ * Initial release.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 Ben Johnson of Binary Logic (binarylogic.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,100 @@
1
+ CHANGELOG.rdoc
2
+ init.rb
3
+ lib/authlogic/active_record/acts_as_authentic.rb
4
+ lib/authlogic/active_record/authenticates_many.rb
5
+ lib/authlogic/active_record/scoped_session.rb
6
+ lib/authlogic/controller_adapters/abstract_adapter.rb
7
+ lib/authlogic/controller_adapters/rails_adapter.rb
8
+ lib/authlogic/session/active_record_trickery.rb
9
+ lib/authlogic/session/base.rb
10
+ lib/authlogic/session/callbacks.rb
11
+ lib/authlogic/session/config.rb
12
+ lib/authlogic/session/errors.rb
13
+ lib/authlogic/sha512_crypto_provider.rb
14
+ lib/authlogic/version.rb
15
+ lib/authlogic.rb
16
+ Manifest
17
+ MIT-LICENSE
18
+ Rakefile
19
+ README.rdoc
20
+ test_app/app/controllers/application.rb
21
+ test_app/app/controllers/companies_controller.rb
22
+ test_app/app/controllers/user_sessions_controller.rb
23
+ test_app/app/controllers/users_controller.rb
24
+ test_app/app/helpers/application_helper.rb
25
+ test_app/app/helpers/companies_helper.rb
26
+ test_app/app/helpers/user_sessions_helper.rb
27
+ test_app/app/helpers/users_helper.rb
28
+ test_app/app/models/company.rb
29
+ test_app/app/models/project.rb
30
+ test_app/app/models/user.rb
31
+ test_app/app/models/user_session.rb
32
+ test_app/app/views/layouts/application.html.erb
33
+ test_app/app/views/user_sessions/new.html.erb
34
+ test_app/app/views/users/_form.erb
35
+ test_app/app/views/users/edit.html.erb
36
+ test_app/app/views/users/new.html.erb
37
+ test_app/app/views/users/show.html.erb
38
+ test_app/config/boot.rb
39
+ test_app/config/database.yml
40
+ test_app/config/environment.rb
41
+ test_app/config/environments/development.rb
42
+ test_app/config/environments/production.rb
43
+ test_app/config/environments/test.rb
44
+ test_app/config/initializers/inflections.rb
45
+ test_app/config/initializers/mime_types.rb
46
+ test_app/config/initializers/new_rails_defaults.rb
47
+ test_app/config/routes.rb
48
+ test_app/db/development.sqlite3
49
+ test_app/db/migrate/20081023040052_create_users.rb
50
+ test_app/db/migrate/20081103003828_create_companies.rb
51
+ test_app/db/migrate/20081103003834_create_projects.rb
52
+ test_app/db/schema.rb
53
+ test_app/db/test.sqlite3
54
+ test_app/doc/README_FOR_APP
55
+ test_app/public/404.html
56
+ test_app/public/422.html
57
+ test_app/public/500.html
58
+ test_app/public/dispatch.cgi
59
+ test_app/public/dispatch.fcgi
60
+ test_app/public/dispatch.rb
61
+ test_app/public/favicon.ico
62
+ test_app/public/images/rails.png
63
+ test_app/public/javascripts/application.js
64
+ test_app/public/javascripts/controls.js
65
+ test_app/public/javascripts/dragdrop.js
66
+ test_app/public/javascripts/effects.js
67
+ test_app/public/javascripts/prototype.js
68
+ test_app/public/robots.txt
69
+ test_app/public/stylesheets/scaffold.css
70
+ test_app/Rakefile
71
+ test_app/README
72
+ test_app/script/about
73
+ test_app/script/console
74
+ test_app/script/dbconsole
75
+ test_app/script/destroy
76
+ test_app/script/generate
77
+ test_app/script/performance/benchmarker
78
+ test_app/script/performance/profiler
79
+ test_app/script/performance/request
80
+ test_app/script/plugin
81
+ test_app/script/process/inspector
82
+ test_app/script/process/reaper
83
+ test_app/script/process/spawner
84
+ test_app/script/runner
85
+ test_app/script/server
86
+ test_app/test/fixtures/companies.yml
87
+ test_app/test/fixtures/projects.yml
88
+ test_app/test/fixtures/users.yml
89
+ test_app/test/functional/companies_controller_test.rb
90
+ test_app/test/functional/user_sessions_controller_test.rb
91
+ test_app/test/functional/users_controller_test.rb
92
+ test_app/test/integration/company_user_session_stories_test.rb
93
+ test_app/test/integration/user_sesion_stories_test.rb
94
+ test_app/test/integration/user_session_config_test.rb
95
+ test_app/test/integration/user_session_test.rb
96
+ test_app/test/test_helper.rb
97
+ test_app/test/unit/account_test.rb
98
+ test_app/test/unit/company_test.rb
99
+ test_app/test/unit/project_test.rb
100
+ test_app/test/unit/user_test.rb
@@ -0,0 +1,292 @@
1
+ = Authlogic
2
+
3
+ Authlogic is "rails authentication done right". Put simply, its the Chuck Norris of authentication solutions.
4
+
5
+ The last thing we need is another authentication solution for rails, right? That'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 "rails like" authentication solution. Authlogic is my attempt to satisfy that need...
6
+
7
+ Wouldn't it be nice to keep your app up to date with the latest and greatest security techniques with a simple update of a plugin?
8
+
9
+ What if you could have authentication up and running in minutes without having to run a generator? All because it's simple, like everything else in rails.
10
+
11
+ What if creating a user session could be as simple as...
12
+
13
+ UserSession.create(params[:user_session])
14
+
15
+ What if your user sessions controller could look just like your other controllers...
16
+
17
+ class UserSessionsController < ApplicationController
18
+ def new
19
+ @user_session = UserSession.new
20
+ end
21
+
22
+ def create
23
+ @user_session = UserSession.new(params[:user_session])
24
+ if @user_session.save
25
+ redirect_to account_url
26
+ else
27
+ render :action => :new
28
+ end
29
+ end
30
+
31
+ def destroy
32
+ @user_session.destroy
33
+ end
34
+ end
35
+
36
+ Look familiar? If you didn't know any better, you would think UserSession was an ActiveRecord model. I think that's pretty cool, because it fits nicely into the RESTful development pattern, a style we all know and love. What about the view...
37
+
38
+ <%= error_messages_for "user_session" %>
39
+ <% form_for @user_session do |f| %>
40
+ <%= f.label :login %><br />
41
+ <%= f.text_field :login %><br />
42
+ <br />
43
+ <%= f.label :password %><br />
44
+ <%= f.password_field :password %><br />
45
+ <br />
46
+ <%= f.submit "Login" %>
47
+ <% end %>
48
+
49
+ Or how about persisting the session...
50
+
51
+ class ApplicationController
52
+ before_filter :load_user
53
+
54
+ protected
55
+ def load_user
56
+ @user_session = UserSession.find
57
+ @current_user = @user_session && @user_session.record
58
+ end
59
+ end
60
+
61
+ Authlogic makes this a reality. This is just the tip of the ice berg. Keep reading to find out everything Authlogic can do.
62
+
63
+ == Helpful links
64
+
65
+ * <b>Documentation:</b> http://authlogic.rubyforge.org
66
+ * <b>Authlogic setup tutorial:</b> coming soon...
67
+ * <b>Live example of the setup tutorial above (with source):</b> coming soon....
68
+ * <b>Bugs / feature suggestions:</b> http://binarylogic.lighthouseapp.com/projects/18752-authlogic
69
+
70
+ == Install and use
71
+
72
+ Install the gem / plugin
73
+
74
+ $ sudo gem install authlogic
75
+ $ cd vendor/plugins
76
+ $ sudo gem unpack authlogic
77
+
78
+ Or as a plugin
79
+
80
+ script/plugin install git://github.com/binarylogic/authlogic.git
81
+
82
+ In an effort to keep this readme a reference instead of a step by step guide, I moved the setup tutorial to my blog. See "helpful links" above. If this is your first time using Authlogic checkout the tutorial.
83
+
84
+ == Magic Columns
85
+
86
+ Just like ActiveRecord has "magic" columns, such as: created_at and updated_at. Authlogic has its own "magic" columns too:
87
+
88
+ Column name Description
89
+ login_count Increased every time an explicit login is made. This will *NOT* increase if logging in by a session, cookie, or basic http auth
90
+ last_request_at Updates every time the user logs in, either by explicitly logging in, or logging in by cookie, session, or http auth
91
+ current_login_at Updates with the current time when an explicit login is made.
92
+ last_login_at Updates with the value of current_login_at before it is reset.
93
+ current_login_ip Updates with the request remote_ip when an explicit login is made.
94
+ last_login_ip Updates with the value of current_login_ip before it is reset.
95
+
96
+ == Magic States
97
+
98
+ Authlogic tries to check the state of the record before creating the session. If your record responds to the following methods and any of them return false, validation will fail:
99
+
100
+ Method name Description
101
+ active? Is the record marked as active?
102
+ approved? Has the record been approved?
103
+ confirmed? Has the record been conirmed?
104
+
105
+ What's neat about this is that these are checked upon any type of login. When logging in explicitly, by cookie, session, or basic http auth. So if you mark a user inactive in the middle of their session they wont be logged back in next time they refresh the page. Giving you complete control.
106
+
107
+ Need Authlogic to check your own "state"? No problem, check out the hooks section below. Add in a before_validation or after_validation to do your own checking.
108
+
109
+ == Hooks / Callbacks
110
+
111
+ Just like ActiveRecord you can create your own hooks / callbacks so that you can do whatever you want when certain actions are performed. Here they are:
112
+
113
+ before_create
114
+ after_create
115
+ before_destroy
116
+ after_destroy
117
+ before_save
118
+ after_save
119
+ before_update
120
+ after_update
121
+ before_validation
122
+ after_validation
123
+
124
+ == Multiple Sessions / Session Identifiers
125
+
126
+ You're asking: "why would I want multiple sessions?". Take this example:
127
+
128
+ You have an app where users login and then need to re-login to view / change their billing information. Similar to how Apple's me.com works. What you could do is have the user login with their normal session, then have an entirely new session that represents their "secure" session. But wait, this is 2 users sessions. No problem:
129
+
130
+ # regular user session
131
+ @user_session = UserSession.new
132
+ @user_session.id
133
+ # => nil
134
+
135
+ # secure user session
136
+ @secure_user_session = UserSession.new(:secure)
137
+ @secure_user_session.id
138
+ # => :secure
139
+
140
+ This will keep everything separate. The :secure session will store its info in a separate cookie, separate session, etc. Just set the id and you are good to go. Need to retrieve the session?
141
+
142
+ @user_session = UserSession.find
143
+ @secure_user_session = UserSession.find(:secure)
144
+
145
+ For more information on ids checkout Authlogic::Session::Base#initialize
146
+
147
+ == Scoping
148
+
149
+ Scoping with authentication is a little tricky because it can come in many different flavors:
150
+
151
+ 1. Accounts have many users, meaning users can only belong to one account at a time.
152
+ 2. Accounts have and belong to many users, meaning a user can belong to more than one account.
153
+ 3. Users access their accounts via subdomains.
154
+ 4. Users access their accounts by selecting their account and storing their selection, *NOT* using subdomains. Maybe you store their selection in a session, cookie, or the database. It doesn't matter.
155
+
156
+ Now mix and match the above, it can get pretty hairy. Fear not, because Authlogic is designed in a manner where it doesn't care how you do it, all that you have to do is break it down. When scoping a session there are 3 parts you might want to scope:
157
+
158
+ 1. The model (the validations, etc)
159
+ 2. The session (finding the record)
160
+ 3. The cookies (the names of the session key and cookie)
161
+
162
+ I will describe each below, in order.
163
+
164
+ === Scoping your model
165
+
166
+ This scopes your login field validation, so that users are allowed to have the same login, just not in the same account.
167
+
168
+ # app/models/user.rb
169
+ class User < ActiveRecord::Base
170
+ acts_as_authentic :scope => :account_id
171
+ end
172
+
173
+ === Scoping your session
174
+
175
+ When you session tries to validate it searches for a record. You want to scope that search. No problem...
176
+
177
+ The goal of Authlogic was to not try and introduce anything new. As a result I came up with:
178
+
179
+ @account.user_sessions.find
180
+ @account.user_sessions.create
181
+ @account.user_sessions.build
182
+ # ... etc
183
+
184
+ This works just like ActiveRecord, so it should come natural. Here is how you get this functionality:
185
+
186
+ class Account < ActiveRecord::Base
187
+ authenticates_many :user_sessions
188
+ end
189
+
190
+ === Scoping cookies
191
+
192
+ What's neat about cookies is that if you use sub domains they automatically scope their self. Meaning if you create a cookie in whatever.yourdomain.com it will not exist in another.yourdomain.com. So if you have the example used above, where you can access accounts via a sub domain, you don't have to do anything.
193
+
194
+ But what if you don't want to separate your cookies by subdomains? You can accomplish this by doing:
195
+
196
+ ActionController::Base.session_options[:session_domain] = ‘.mydomain.com’
197
+
198
+ If for some reason the above doesn't work for you, do some simple Google searches. There are a million blog posts on this.
199
+
200
+ Now let's look at this from the other angle. What if you are *NOT* using subdomains, but still want to separate cookies for each account. Simple, set the :scope_cookies option for authenticate_many:
201
+
202
+ class Account < ActiveRecord::Base
203
+ authenticates_many :user_sessions, :scope_cookies => true
204
+ end
205
+
206
+ Done, Authlogic will give each cookie a unique name depending on the account.
207
+
208
+ With the above information you should be able to scope your sessions any way you want. Just mix and match the tools above to accomplish what you want. Also check out the documentation on Authlogic::ActiveRecord::AuthenticatesMany.
209
+
210
+ == Errors
211
+
212
+ The errors in Authlogic work JUST LIKE ActiveRecord. In fact, it uses the exact same ActiveRecord errors class. Use it the same way:
213
+
214
+ class UserSession
215
+ before_validation :check_if_awesome
216
+
217
+ private
218
+ def check_if_awesome
219
+ errors.add(:login, "must contain awesome") if login && !login.include?("awesome")
220
+ errors.add_to_base("You must be awesome to log in") unless record.awesome?
221
+ end
222
+ end
223
+
224
+ == Automatic Session Updating
225
+
226
+ This is one of my favorite features that I think is pretty cool. It's things like this that make a library great and let you know you are on the right track.
227
+
228
+ 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.
229
+
230
+ 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'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't matter, your code should be written in a way where you don't have to remember to do this.
231
+
232
+ Instead of updating sessions all over the place, doesn't it make sense to do this at a lower level? Like the User model? You're saying "but Ben, models can't mess around with sessions and cookies". True...but Authlogic can, and you can access Authlogic just like a model. I know in most situations it'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.
233
+
234
+ Fear not, because the acts_as_authentic method you call in your model takes care of this for you, by adding an after_save callback to automatically keep the session up to date. You don't have to worry about it anymore. Don't even think about it. Let your UsersController deal with users, not users *AND* sessions. *ANYTIME* the user changes his password in *ANY* way, his session will be updated.
235
+
236
+ Here is basically how this is done....
237
+
238
+ class User < ActiveRecord::Base
239
+ after_save :maintain_sessions!
240
+ after_update :update_sessions!
241
+
242
+ private
243
+ def maintain_sessions!
244
+ # If we aren't logged in at all and the password was changed, go ahead and log the user in
245
+ # If we are logged in and the password has change, update the sessions
246
+ end
247
+ end
248
+
249
+ Obviously there is a little more to it than this, but hopefully this clarifies any confusion. Lastly, this can be altered / disabled via a configuration option. Just set :session_ids => nil when calling acts_as_authentic.
250
+
251
+ 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!
252
+
253
+ == What about [insert framework here]?
254
+
255
+ As of now, authlogic supports rails right out of the box. But I designed authlogic to be framework agnostic. The only thing stopping Authlogic from being implemented in merb, or any other framework, is a simple adapter. I have not had the opportunity to use Authlogic in anything other than rails. If you want to use this in merb or any other framework take a look at authlogic/controller/rails_adapter.rb.
256
+
257
+ == How it works
258
+
259
+ Interested in how all of this all works? Basically a before_filter is automatically set in your controller which lets Authlogic know about the current controller object. This "activates" Authlogic and allows Authlogic to set sessions, cookies, login via basic http auth, etc. If you are using rails in a multiple thread environment, don't worry. I kept that in mind and made this thread safe.
260
+
261
+ From there it is pretty simple. When you try to create a new session the record is authenticated and then all of the session / cookie magic is done for you. The sky is the limit.
262
+
263
+ == What's wrong with the current solutions?
264
+
265
+ You probably don't care, but I think releasing the millionth authentication solution for a framework that has been around for over 4 years requires a little explanation.
266
+
267
+ I don't necessarily think the current solutions are "wrong", nor am I saying Authlogic is the answer to your prayers. But, to me, the current solutions were lacking something. Here's what I came up with...
268
+
269
+ === Generators are messy
270
+
271
+ Generators have their place, and it is not to add authentication to a rails app. It doesn't make sense. Generators are meant to be a starting point for repetitive tasks that have no sustainable pattern. Take controllers, the set up is the same thing over and over, but they eventually evolve to a point where there is no clear cut pattern. Trying to extract a pattern out into a library would be extremely hard, messy, and overly complicated. As a result, generators make sense here.
272
+
273
+ Authentication is a one time set up process for your app. It's the same thing over and over and the pattern never really changes. The only time it changes is to conform with newer / stricter security techniques. This is exactly why generators should not be an authentication solution. Generators add code to your application, once code crosses that line, you are responsible for maintaining it. You get to make sure it stays up with the latest and greatest security techniques. And when the plugin you used releases some major update, you can't just re-run the generator, you get to sift through the code to see what changed. You don't really have a choice either, because you can't ignore security updates.
274
+
275
+ Using a library that hundreds of other people use has it advantages. Probably one of the biggest advantages if that you get to benefit from other people using the same code. When Bob in California figures out a new awesome security technique and adds it into Authlogic, you get to benefit from that with a single update. The catch is that this benefit is limited to code that is not "generated" or added into your app. As I said above, once code is "generated" and added into your app, it's your responsibility.
276
+
277
+ Lastly, there is a pattern here, why clutter up all of your applications with the same code over and over?
278
+
279
+ === Limited to a single authentication
280
+
281
+ I recently had an app where you could log in as a user and also log in as an employee. I won't go into the specifics of the app, but it made the most sense to do it this way. So I had two sessions in one app. None of the current solutions I found easily supported this. They all assumed a single session. One session was messy enough, adding another just put me over the edge and eventually forced me to write Authlogic. Authlogic can support 100 different sessions easily and in a clean format. Just like an app can support 100 different models and 100 different records of each model.
282
+
283
+ === Too presumptuous
284
+
285
+ A lot of them forced me to name my password column as "this", or the key of my cookie had to be "this". They were a little too presumptuous. I am probably overly picky, but little details like that should be configurable. This also made it very hard to implement into an existing app.
286
+
287
+ === Disclaimer
288
+
289
+ I am not trying to "bash" any other authentication solutions. These are just my opinions, formulate your own opinion. I released Authlogic because it has made my life easier and I enjoy using it, hopefully it does the same for you.
290
+
291
+
292
+ Copyright (c) 2008 Ben Johnson of [Binary Logic](http://www.binarylogic.com), released under the MIT license