Статьи

Изучение разработки, часть 1

В некоторых моих предыдущих статьях о загрузке изображений в Rails я упоминал Devise, но не углублялся в это. В этом уроке я расскажу вам о Devise.

Готов? Давайте начнем!

Devise — это решение для аутентификации Rails, созданное с помощью Warden и предоставленное замечательными людьми из Plataformatec . Devise предоставляет различные модули:

  • Проверка подлинности базы данных: при этом шифруется и сохраняется пароль к базе данных для проверки подлинности пользователя при входе в систему.
  • Omniauthable: это прикрепляет поддержку OmniAuth к Devise. Пользователи вашего приложения смогут войти, используя такие учетные записи, как Facebook, Twitter и Google.
  • Подтверждаемый: это позволяет отправлять электронные письма с инструкциями, которые помогут в проверке учетной записи.
  • Восстанавливаемый: Этот модуль помогает в случаях, когда пользователи забывают свой пароль и нуждаются в его восстановлении. При этом пользователь сможет сбросить пароль.
  • Регистрируемый: Это обрабатывает регистрацию пользователей. Это также позволяет пользователям редактировать и удалять свои учетные записи.
  • Запоминаемый: Этот модуль позволяет вашему приложению запомнить зарегистрированного пользователя, сохранив cookie.
  • Отслеживается: этот модуль помогает отслеживать количество входов в систему, отметки времени и IP-адрес.
  • График времени: этот модуль отвечает за истечение сеанса, который не был активным в течение определенного периода времени.
  • Validatable: с этим модулем, электронная почта и пароль должны быть проверены.
  • Блокируемый: это обеспечивает дополнительный уровень безопасности — при активации учетная запись может быть заблокирована после определенного числа неудачных попыток входа.

Для целей данного руководства мы создадим приложение Rails, которое мы будем использовать для проверки работы Devise. Давайте продолжим!

rails new devise-app -T

Флаг -T указывает Rails генерировать приложение без набора тестов по умолчанию. Перейдите в каталог своего приложения и Gemfile следующие гемы в свой Gemfile .

1
2
3
4
#Gemfile
 
gem ‘devise’, ‘~> 4.1’
gem ‘bootstrap-sass’, ‘~> 3.3’

Теперь установите драгоценные камни Devise и Bootstrap, которые вы только что добавили.

bundle install

Переименуйте файл app/assets/stylesheets/application.css в app/assets/stylesheets/application.scss и добавьте в него следующие строки:

1
2
3
4
#app/assets/stylesheets/application.scss
 
@import «bootstrap-sprockets»;
@import «bootstrap»;

Откройте файл app/assets/javascripts/application.js и потребуйте bootstrap-sprockets . Моя выглядит так:

1
2
3
4
5
6
7
#app/assets/javascripts/application.js
 
//= require jquery
//= require bootstrap-sprockets
//= require jquery_ujs
//= require turbolinks
//= require_tree .

Далее вам нужно запустить команду Rails, чтобы установить файлы конфигурации для Devise. Вы делаете это с помощью этой команды:

rails generate devise:install

Команда генерирует следующее на вашем терминале. Вы должны прочитать это, чтобы понять, что случилось.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
create config/initializers/devise.rb
     create config/locales/devise.en.yml
===============================================================================
 
Some setup you must do manually if you haven’t yet:
 
 1. Ensure you have defined default url options in your environments files.
    is an example of default_url_options appropriate for a development environment
    in config/environments/development.rb:
 
      config.action_mailer.default_url_options = { host: ‘localhost’, port: 3000 }
 
    In production, :host should be set to the actual host of your application.
 
 2. Ensure you have defined root_url to *something* in your config/routes.rb.
    For example:
 
      root to: «home#index»
 
 3. Ensure you have flash messages in app/views/layouts/application.html.erb.
    For example:
 
      <p class=»notice»><%= notice %></p>
      <p class=»alert»><%= alert %></p>
 
 4. If you are deploying on Heroku with Rails 3.2 only, you may want to set:
 
      config.assets.initialize_on_precompile = false
 
    On config/application.rb forcing your application to not access the DB
    or load models when precompiling your assets.
 
 5. You can copy Devise views (for customization) to your app by running:
 
      rails g devise:views
 
      ===============================================================================

Команда также генерирует два файла, которые вы можете найти в каталоге config . Это также дает нам некоторые инструкции о том, что мы должны делать.

Перейдите к макету app/views/layouts/application.html.erb , app/views/layouts/application.html.erb , и сделайте так, как показано ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
#app/views/layouts/application.html.erb
 
<!DOCTYPE html>
<html>
<head>
  <title>DeviseApp</title>
  <%= stylesheet_link_tag ‘application’, media: ‘all’, ‘data-turbolinks-track’ => true %>
  <%= javascript_include_tag ‘application’, ‘data-turbolinks-track’ => true %>
  <%= csrf_meta_tags %>
</head>
<body>
  <div class=»container-fluid»>
    <p class=»notice»><%= notice %></p>
    <p class=»alert»><%= alert %></p>
  </div>
 
  <div class=»container-fluid»>
    <%= yield %>
  </div>
 
</body>
</html>

Вам необходимо определить параметры URL по умолчанию для вашей среды разработки. Добавьте приведенный ниже код в config/environments/development.rb .

1
2
3
#config/environments/development.rb
 
config.action_mailer.default_url_options = { host: ‘localhost’, port: 3000 }

Теперь вам нужно создать User модель для Devise. Вы можете сделать это, используя свой терминал.

rails generate devise User

Это создаст файл user.rb в вашем каталоге app/models . Сгенерированный файл будет выглядеть так:

1
2
3
4
5
6
class User < ActiveRecord::Base
  # Include default devise modules.
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

Вы можете видеть, что он содержит модули по умолчанию, которые я упоминал выше. Команда, которую вы запустили, также изменила ваш файл config/routes.rb , добавив маршрут для devise. Вы должны это проверить.

На данный момент вам нужно перенести вашу базу данных. Вы делаете это, запустив:

rake db:migrate

Теперь вам нужно создать PagesController и обернуть вокруг него аутентификацию Devise — это предотвратит просмотр страницы неуполномоченными лицами.

rails generate controller Pages index

Откройте файл маршрутов и установите корень вашего приложения.

1
2
3
4
5
6
#config/routes.rb
 
Rails.application.routes.draw do
  devise_for :users
  root to: «pages#index»
end

Откройте ваш PagesController и добавьте аутентификацию для вашего index и new страниц.

01
02
03
04
05
06
07
08
09
10
11
#app/controllers/pages_controller.rb
 
class PagesController < ApplicationController
  before_action :authenticate_user!, only: [:index, :new]
 
  def index
  end
 
  def new
  end
end

Код показывает, что index и new страницы доступны только зарегистрированным пользователям. Откройте свой терминал и запустите rails server . Укажите в браузере http://localhost:3000 и вы автоматически будете перенаправлены на страницу входа в Devise.

Средства входа в Devise по умолчанию включают использование адреса электронной почты и пароля. Что если вы хотите, чтобы пользователи могли входить под своим уникальным именем пользователя? Если это то, что вы хотите, это возможно. Посмотрим как.

Запустите команду:

rails generate migration AddUsernameToUSers username:string

Это добавит новый столбец для username в вашей таблице users . Перенос вашей базы данных.

rake db:migrate

Вам необходимо добавить поле для ваших просмотров, где ваши пользователи могут ввести свое имя пользователя. Когда вы зайдете в каталог app/views , вы не найдете файл, который отображает представления Devise. Это потому, что Devise загружает представления из своего набора гемов. Чтобы настроить его, вы должны сгенерировать копии представлений. Команда ниже делает волшебство.

rails generate devise:views

Это создаст несколько папок и файлов в вашем каталоге app/views .

Вам нужно будет отредактировать страницу для входа, регистрации и обновления информации о пользователе. Просто вставьте блоки кода ниже в соответствующие файлы.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#app/views/devise/registrations/new.html.erb
 
<h2>Sign up</h2>
 
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
  <%= devise_error_messages!
 
  <div class=»form-group»>
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, class: «form-control» %>
  </div>
 
  <div class=»form-group»>
    <%= f.label :username %>
    <%= f.text_field :username, class: «form-control» %>
  </div>
 
  <div class=»form-group»>
    <%= f.label :password %>
    <% if @minimum_password_length %>
    <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: «off», class: «form-control» %>
  </div>
 
  <div class=»form-group»>
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: «off», class: «form-control» %>
  </div>
 
  <div class=»actions»>
    <%= f.submit «Sign up», class: «btn btn-primary» %>
  </div>
<% end %>
 
<%= render «devise/shared/links» %>
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#app/views/devise/registrations/edit.html.erb
 
<h2>Edit <%= resource_name.to_s.humanize %></h2>
 
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
  <%= devise_error_messages!
 
  <div class=»form-group»>
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, class: «form-control» %>
  </div>
 
  <% if devise_mapping.confirmable?
    <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
  <% end %>
 
  <div class=»form-group»>
    <%= f.label :username %>
    <%= f.text_field :username, class: «form-control» %>
  </div>
 
  <div class=»form-group»>
    <%= f.label :password %> <i>(leave blank if you don’t want to change it)</i><br />
    <%= f.password_field :password, autocomplete: «off», class: «form-control» %>
  </div>
 
  <div class=»form-group»>
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: «off», class: «form-control» %>
  </div>
 
  <div class=»form-group»>
    <%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
    <%= f.password_field :current_password, autocomplete: «off», class: «form-control» %>
  </div>
 
  <div class=»actions»>
    <%= f.submit «Update», class: «btn btn-primary» %>
  </div>
<% end %>
 
<h3>Cancel my account</h3>
 
<p>Unhappy?
 
<%= link_to «Back», :back %>
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#app/views/devise/sessions/new.html.erb
 
<h2>Log in</h2>
 
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
  <div class=»form-group»>
    <%= f.label :username %><br />
    <%= f.text_field :username, autofocus: true, class: «form-control» %>
  </div>
 
  <div class=»form-group»>
    <%= f.label :password %><br />
    <%= f.password_field :password, autocomplete: «off», class: «form-control» %>
  </div>
 
  <% if devise_mapping.rememberable?
    <div class=»form-group»>
      <%= f.check_box :remember_me %>
      <%= f.label :remember_me %>
    </div>
  <% end -%>
 
  <div class=»actions»>
    <%= f.submit «Log in», class: «btn btn-primary» %>
  </div>
<% end %>
 
<%= render «devise/shared/links» %>

Используя ваш текстовый редактор, перейдите в app/controllers/application_controller.rb . Вам нужно изменить его, чтобы разрешить использование имени пользователя. Измените его так, чтобы оно выглядело так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
#app/controllers/application_controller.rb
 
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
 
  before_action :configure_permitted_parameters, if: :devise_controller?
 
  protected
 
  def configure_permitted_parameters
    added_attrs = [:username, :email, :password, :password_confirmation, :remember_me]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
  end
end

Теперь пользователь может войти под своим именем. На данный момент в вашем приложении что-то не так. Когда пользователь входит в систему, нет возможности выйти. Это не приводит к большому опыту пользователя. Я покажу вам, как это исправить.

В своем терминале создайте новый каталог с именем shared в папке app/views .

1
2
mkdir app/views/shared
touch app/views/shared/_navigation.html.erb

Файл, который вы создали выше, является частичным, где будет написан код вашей панели навигации. Загляните в следующий код.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#app/views/shared/_navigation.html.erb
 
<nav class=»navbar navbar-inverse»>
  <div class=»container»>
    <div class=»navbar-header»>
      <%= link_to ‘Tutsplus Devise’, root_path, class: ‘navbar-brand’ %>
    </div>
    <div id=»navbar»>
      <ul class=»nav navbar-nav»>
        <li><%= link_to ‘Home’, root_path %></li>
      </ul>
      <ul class=»nav navbar-nav pull-right»>
        <% if user_signed_in?
          <li class=»dropdown»>
            <a class=»dropdown-toggle» data-toggle=»dropdown» href=»#»>
              <%= current_user.name %>
              <span class=»caret»>
            </a>
            <ul class=»dropdown-menu» role=»menu»>
              <li><%= link_to ‘Profile’, edit_user_registration_path %></li>
              <li><%= link_to ‘Log out’, destroy_user_session_path, method: :delete %></li>
            </ul>
          </li>
        <% else %>
          <li><%= link_to ‘Log In’, new_user_session_path %></li>
          <li><%= link_to ‘Sign Up’, new_user_registration_path %></li>
        <% end %>
      </ul>
    </div>
  </div>
</nav>

Теперь вам нужно отобразить панель навигации в макете приложения. Откройте app/views/layouts/application.html.erb и вставьте код, чтобы отобразить панель навигации.

01
02
03
04
05
06
07
08
09
10
#app/views/layouts/application.html.erb
 
<div class=»container-fluid»>
  <%= render «shared/navigation» %>
 
  <p class=»notice»><%= notice %></p>
  <p class=»alert»><%= alert %></p>
</div>

В этой части вы узнали, как установить Devise и добавить аутентификацию на свои страницы. Я также упомянул частичное. Я расскажу об этом в отдельном уроке.

В следующей части мы рассмотрим некоторые области, более продвинутые, чем эта. Я надеюсь, что это стоило вашего времени!