Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 210 lines (143 sloc) 10.069 kb
1b98335 @binarylogic Initial commit
authored
1 = Authgasm
2
e77ca8a @binarylogic Updated readme
authored
3 Authgasm is "rails authentication done right"
1b98335 @binarylogic Initial commit
authored
4
34b225c @binarylogic Updated readme
authored
5 The last thing we need is another authentication solution for rails, right? That's what I thought. It was disappointing to find that all of the solutions were overly complicated, bloated, written poorly, and were just plain confusing. They felt very Windowsish. This is not the simple / elegant rails we all fell in love with. It's like the Microsoft engineers decided to dabble in ruby / rails for a day and their project was to write an authentication solution. That's what went through my head when I was trying out all of the current solutions. It's time we need a "rails like" authentication solution. So I give you Authgasm...
1b98335 @binarylogic Initial commit
authored
6
34b225c @binarylogic Updated readme
authored
7 What if creating a user session could be as simple as...
e77ca8a @binarylogic Updated readme
authored
8
9 UserSession.create(params[:user])
10
34b225c @binarylogic Updated readme
authored
11 What if your user sessions controller could look just like your other controllers...
1b98335 @binarylogic Initial commit
authored
12
13 class UserSessionsController < ApplicationController
14 def new
15 @user_session = UserSession.new
16 end
17
18 def create
19 @user_session = UserSession.new(params[:user_session])
20 if @user_session.create
c93bec2 @binarylogic Changed scope to id
authored
21 redirect_to account_url
1b98335 @binarylogic Initial commit
authored
22 else
23 render :action => :new
24 end
25 end
26
27 def destroy
28 @user_session.destroy
29 end
30 end
31
32 Look familiar? If you didn't know any better, you would think UserSession was an ActiveRecord model. I think that'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't this be cool too...
33
34 <%= error_messages_for "user_session" %>
35 <% form_for @user_session do |f| %>
36 <%= f.label :login %><br />
37 <%= f.text_field :login %><br />
38 <br />
39 <%= f.label :password %><br />
40 <%= f.password_field :password %><br />
41 <br />
42 <%= f.submit "Login" %>
43 <% end %>
44
34b225c @binarylogic Updated readme
authored
45 Or how about persisting the session...
1b98335 @binarylogic Initial commit
authored
46
47 class ApplicationController
48 before_filter :load_user
49
50 protected
51 def load_user
52 @user_session = UserSession.find
53 @current_user = @user_session && @user_session.record
54 end
55 end
56
34b225c @binarylogic Updated readme
authored
57 Authgasm makes this a reality. This is just the tip of the ice berg. Keep reading to find out everything Authgasm can do.
1b98335 @binarylogic Initial commit
authored
58
59 == Helpful links
60
61 * <b>Documentation:</b> http://authgasm.rubyforge.org
62 * <b>Authgasm tutorial:</b> coming soon...
63 * <b>Live example of the tutorial above (with source):</b> coming soon....
64 * <b>Bugs / feature suggestions:</b> http://binarylogic.lighthouseapp.com/projects/18752-authgasm
65
66 == Install and use
67
68 === Install the gem / plugin
69
70 $ sudo gem install authgasm
71 $ cd vendor/plugins
72 $ sudo gem unpack authgasm
73
74 Or as a plugin
75
76 script/plugin install git://github.com/binarylogic/authgasm.git
77
77798f2 @binarylogic Updated installation guide
authored
78 === Create your session
1b98335 @binarylogic Initial commit
authored
79
77798f2 @binarylogic Updated installation guide
authored
80 For this walk through lets assume you are setting up a session for your User model.
1b98335 @binarylogic Initial commit
authored
81
77798f2 @binarylogic Updated installation guide
authored
82 Create your user_session.rb file:
1b98335 @binarylogic Initial commit
authored
83
77798f2 @binarylogic Updated installation guide
authored
84 # app/models/user_session.rb
85 class UserSession < Authgasm::Session::Base
86 # configuration here, just like ActiveRecord, or in an initializer
87 # See Authgasm::Session::Config::ClassMethods for more details
88 end
1b98335 @binarylogic Initial commit
authored
89
77798f2 @binarylogic Updated installation guide
authored
90 It is important to set your configuration for your session before you set the configuration for your model. This will save you some time. Your model will try to guess its own configuration based on what you set in the session. These are completely separate, making Authgasm as flexible as it needs to be, but no one likes to repeat their self.
1b98335 @binarylogic Initial commit
authored
91
77798f2 @binarylogic Updated installation guide
authored
92 == Ensure proper database fields
1b98335 @binarylogic Initial commit
authored
93
94 The user model needs to have the following columns. The names of these columns can be changed with configuration.
95
96 t.string :login, :null => false
97 t.string :crypted_password, :null => false
98 t.string :password_salt, :null => false # not needed if you are encrypting your pw instead of using a hash algorithm
99 t.string :remember_token, :null => false
c00672f @binarylogic Updated automatic session maintenance
authored
100 t.integer :login_count # This is optional, it is a "magic" column, just like "created_at". See below for a list of all magic columns.
1b98335 @binarylogic Initial commit
authored
101
77798f2 @binarylogic Updated installation guide
authored
102 === Set up your model
1b98335 @binarylogic Initial commit
authored
103
77798f2 @binarylogic Updated installation guide
authored
104 Make sure you have a model that you will be authenticating with. For this example let's say you have a User model:
105
106 class User < ActiveRecord::Base
107 acts_as_authentic # for options see documentation: Authgasm::ActsAsAuthentic::ClassMethods
1b98335 @binarylogic Initial commit
authored
108 end
109
110 Done! Now go use it just like you would with any other ActiveRecord model (see above).
111
112 == Magic Columns
113
114 Just like ActiveRecord has "magic" columns, such as: created_at and updated_at. Authgasm has its own "magic" columns too:
115
116 Column name Description
117 login_count Increased every time and explicit login is made. This will *NOT* increase if logging in by a session, cookie, or basic http auth
e77ca8a @binarylogic Updated readme
authored
118 last_request_at Updates every time the user logs in, either by explicitly logging in, or logging in by cookie, session, or http auth
1b98335 @binarylogic Initial commit
authored
119 current_login_at Updates with the current time when an explicit login is made.
120 last_login_at Updates with the value of current_login_at before it is reset.
121 current_login_ip Updates with the request remote_ip when an explicit login is made.
122 last_login_ip Updates with the value of current_login_ip before it is reset.
123
124 == Magic States
125
126 Authgasm 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:
127
128 Method name Description
129 approved? Has the record been approved?
130 confirmed? Has the record been conirmed?
131 inactive? Is the record marked as inactive?
132
ff67374 @binarylogic Cleaned up identifier doc
authored
133 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.
1b98335 @binarylogic Initial commit
authored
134
135 == Hooks / Callbacks
136
137 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:
138
139 before_create
140 after_create
141 before_destroy
142 after_destroy
143 before_update
144 after_update
145 before_validation
146 after_validation
147
148 == Automatic Session Updating
149
718f2cf @binarylogic Updated readme on session updating
authored
150 This is one of my favorite features that I think its pretty cool. It's things like this that make a library great and set it apart from other libraries.
151
152 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.
153
34b225c @binarylogic Updated readme
authored
154 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 Authgasm can, and you can access Authgasm 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.
718f2cf @binarylogic Updated readme on session updating
authored
155
34b225c @binarylogic Updated readme
authored
156 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'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.
718f2cf @binarylogic Updated readme on session updating
authored
157
34b225c @binarylogic Updated readme
authored
158 Here is basically how this is done....
1b98335 @binarylogic Initial commit
authored
159
34b225c @binarylogic Updated readme
authored
160 class User < ActiveRecord::Base
161 after_create :create_sessions!
162 after_update :update_sessions!
163
164 private
165 def create_sessions!
166 # create a new UserSession if they are not logged in
167 end
168
169 def update_sessions!
170 # find their session
171 # check that their session's record is the same one as this one: session.record == self
172 # update the session with the new info: session.update
173 end
174 end
175
176 Obviously there is a little more to it than this, but hopefully this clarifies any confusion.
1b98335 @binarylogic Initial commit
authored
177
178 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!
179
ff67374 @binarylogic Cleaned up identifier doc
authored
180 == Multiple Sessions / Session Identifiers
bf796a0 @binarylogic Added info in the readme on multiple sessions
authored
181
182 You're asking: "why would I want multiple sessions?". Take this example:
183
ff67374 @binarylogic Cleaned up identifier doc
authored
184 You have an app where users login and then need to re-login to view / change their billing information. Similar to how Apples' me.com works, if you've ever used it. 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:
bf796a0 @binarylogic Added info in the readme on multiple sessions
authored
185
186 # regular user session
187 @user_session = UserSession.new
188 @user_session.id
189 # => nil
190
191 # secure user session
192 @secure_user_session = UserSession.new(:secure)
193 @secure_user_session.id
194 # => :secure
195
7c5c3cb @binarylogic Added info in the readme on multiple sessions
authored
196 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?
197
198 @user_session = UserSession.find
199 @secure_user_session = UserSession.find(:secure)
200
201 For more information on ids checkout Authgasm::Session::Base#initialize
bf796a0 @binarylogic Added info in the readme on multiple sessions
authored
202
1b98335 @binarylogic Initial commit
authored
203 == How it works
204
ff67374 @binarylogic Cleaned up identifier doc
authored
205 Interested in how all of this all works? Basically a before_filter is automatically set in your controller which lets Authgasm know about the current controller object. This allows Authgasm 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 is thread safe.
1b98335 @binarylogic Initial commit
authored
206
77798f2 @binarylogic Updated installation guide
authored
207 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.
1b98335 @binarylogic Initial commit
authored
208
209
210 Copyright (c) 2008 Ben Johnson of [Binary Logic](http://www.binarylogic.com), released under the MIT license
Something went wrong with that request. Please try again.