📜 ⬆️ ⬇️

Authorization in Ruby on Rails using the restful-authentication plugin

Sitting in Moscow (as here you are crowded :), I found time to write a series of articles on Rails.
Today's theme is inspired by a sad message . So my task: to show how you can easily make authorization in Ruby on Rails. The task of newbies to read and try, the task of newbies to read and write how to do better and / or point out mistakes.

Used tools:

Standard operations:

rails auth -d [ ]
cd auth
rm public/index.html
[ config/database.yml]
rake db:create

For authorization in RoR there are a bunch of plugins. I will use restful-authentication .
The installation is fairly standard:

script/plugin install git://github.com/technoweenie/restful-authentication.git

Now you need to create a user model in which the login password and other user-related data will be stored. Just need two controllers. One for registration and the other for login / logout. Let the user model be user, and the controller for the logout login login sessions, then run the following command:
')
script/generate authenticated user sessions

the plugin will do everything for us. This generator has several options, for example --include-activation, which will add user activation by e-mail. For more information, I recommend to consult the documentation.
The generator will create two users and sessions controllers, a user model, a migration for the user model, entries in config / routes.rb, and a couple of wiyh which you will most likely immediately replace with your own.
Routes look like this:
Copy Source | Copy HTML<br/> ActionController::Routing ::Routes.draw do |map|<br/> map.logout '/logout' , :controller => 'sessions' , :action => 'destroy' <br/> map.login '/login' , :controller => 'sessions' , :action => 'new' <br/> map.register '/register' , :controller => 'users' , :action => 'create' <br/> map.signup '/signup' , :controller => 'users' , :action => 'new' <br/> map.resources :users<br/> map.resource :session<br/> end <br/>

As you can see, everything fits pretty well in REST:

sessions/new [GET]
sessions [POST]
sessions [DELETE] logout
users/new [GET]
users [POST]

I recommend using the options of the routes (entered not so long ago, I do not remember which version): only and: except, edit the map.resources: users record (map.resources: users,: except => [: edit,: update,: destroy], for example). For example, editing is better to move to a separate route: map.resource: profile, (editing in this case will look like this: / profile / edit), since most likely in your application, some users of others should not edit.
Let's look at the app / models / user.rb model:

Copy Source | Copy HTML<br/> require 'digest/sha1' <br/> <br/> class User < ActiveRecord::Base <br/> include Authentication<br/> include Authentication::ByPassword<br/> include Authentication::ByCookieToken<br/> <br/> validates_presence_of : login <br/> validates_length_of : login , :within => 3 .. 40 <br/> validates_uniqueness_of : login <br/> validates_format_of : login , :with => Authentication.login_regex, :message => Authentication.bad_login_message<br/> <br/> validates_format_of :name, :with => Authentication.name_regex, :message => Authentication.bad_name_message, :allow_nil => true <br/> validates_length_of :name, :maximum => 100 <br/> <br/> validates_presence_of : email <br/> validates_length_of : email , :within => 6 .. 100 <br/> validates_uniqueness_of : email <br/> validates_format_of : email , :with => Authentication.email_regex, :message => Authentication.bad_email_message<br/> <br/> attr_accessible : login , : email , :name, :password, :password_confirmation<br/> <br/> def self .authenticate( login , password)<br/> return nil if login .blank? || password.blank?<br/> u = find_by_login( login .downcase) # need to get the salt <br/> u && u.authenticated?(password) ? u : nil <br/> end <br/> <br/> def login =(value)<br/> write_attribute : login , (value ? value.downcase : nil )<br/> end <br/> <br/> def email =(value)<br/> write_attribute : email , (value ? value.downcase : nil )<br/> end <br/> end <br/>


In principle, nothing interesting except that I do not quite like that the login is not an e-mail. To fix this, you need to do the following: remove the t.column entry from the db / migrate / xxxx_users.rb migration: login,: string,: limit => 40. Make the user model like this:
Copy Source | Copy HTML<br/> require 'digest/sha1' <br/> <br/> class User < ActiveRecord::Base <br/> include Authentication<br/> include Authentication::ByPassword<br/> include Authentication::ByCookieToken<br/> <br/> validates_format_of :name, :with => Authentication.name_regex, :message => Authentication.bad_name_message, :allow_nil => true <br/> validates_length_of :name, :maximum => 100 <br/> <br/> validates_presence_of : email <br/> validates_length_of : email , :within => 6 .. 100 <br/> validates_uniqueness_of : email <br/> validates_format_of : email , :with => Authentication.email_regex, :message => Authentication.bad_email_message<br/> <br/> attr_accessible : email , :name, :password, :password_confirmation<br/> <br/> def self .authenticate(login, password)<br/> return nil if login.blank? || password.blank?<br/> u = find_by_email(login.downcase) # need to get the salt <br/> u && u.authenticated?(password) ? u : nil <br/> end <br/> <br/> def email =(value)<br/> write_attribute : email , (value ? value.downcase : nil )<br/> end <br/> end <br/>


The file app / views / users / new.html.erb will also have to be changed:
< h1 > Sign up as a new user </ h1 > <br> <% @user.password = @user.password_confirmation = nil %> <br><br> <% = error_messages_for :user %> <br> <% form_for :user, :url => users_path do |f| - %> <br><br> < p > <% = label_tag 'email' %> < br /> <br> <% = f.text_field :email %> </ p > <br><br> < p > <% = label_tag 'password' %> < br /> <br> <% = f.password_field :password %> </ p > <br><br> < p > <% = label_tag 'password_confirmation' , 'Confirm Password' %> < br /> <br> <% = f.password_field :password_confirmation %> </ p > <br><br> < p > <% = label_tag 'name' %> < br /> <br> <% = f.text_field :name %> </ p > <br><br> < p > <% = submit_tag 'Sign up' %> </ p > <br> <% end - %> <br> <br> * This source code was highlighted with Source Code Highlighter .

All is ready! It remains to complete the migration and run the project.
For completeness, you can add a root route. Root controller generation:

script/generate controller home index

in config / routes.rb add:

map.root :controller => 'home'

Add lightout (app / views / layouts / application.html.erb):
< html > <br> < head > <br> < meta http-equiv ="Content-type" content ="text/html; charset=utf-8" /> <br> < title > auth demo </ title > <br> </ head > <br> < body > <br> <% = render : partial => 'users/user_bar' %> <br> <% = yield %> <br> </ body > <br> </ html > <br><br> * This source code was highlighted with Source Code Highlighter .


Some explanations. In the controller / wihuhe "logging" need to be checked by the function logged_in? (true / false) access to the user who is currently authorized by current_user. Ready project in which there are several corrections not reflected in the article.

Source: https://habr.com/ru/post/53254/


All Articles