[*Rails*] deviseの使い方(rails5版)

  • 125
    いいね
  • 1
    コメント

はじめに

Rails5で再検証版です。
以下のRails4のときのやつを現状(2016/11/12, 13)のバージョンで確認して、一部バージョン上がってうまく動かないところを修正したりした感じです。
[Rails] deviseの使い方

【前回】
rails : 4.2.0
ruby  : 2.2.0
devise: 3.4.1

↓

【今回】
rails : 5.0.0.1
ruby  : 2.3.1
devise: 4.2.0

あと、上の記事で最後に「全部まとめきれてないので、忘れないうちにちょっとずつ追加していこうと思います。」とか書いていながら全く追加することはなかったので、追加しようと思ってたものをちょっとだけ思い出して追加したバージョンです。

deviseとは

ユーザー登録して、送られてきたメールのリンクをクリックして本登録して、ログインして、パスワード忘れたら再設定して、何回もログインミスったらアカウントロックして…などといった認証系アプリに必要な機能を簡単に追加できる便利なgemです。

deviseの導入

1. gemのインストール

1. プロジェクトの作成

新しいプロジェクトを作ります。

$ rails new devise_rails5
$ cd devise_rails5

2. Gemfileの編集とインストール

以下ファイルにdeviseomniauth-twitterを追加します。

Gemfile
source 'https://rubygems.org'

(省略)...

# Devise
gem 'devise'
gem 'omniauth-twitter'

gemをインストール。

$ bundle install

2. deviseの設定

devise関連ファイルを追加。
すると以下のような英文が表示されます。1から4まで順番に見ていきます。

$ rails g devise:install
      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. Here
     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. You can copy Devise views (for customization) to your app by running:

       rails g devise:views

===============================================================================

1. デフォルトURLの指定
英文の例に書いてあったconfig.action_mailer.default_url_options = { host: 'localhost', port: 3000 }を以下のファイルに追加しました。
config.action_mailer.default_url_options = { host: 'localhost:3000' }でもOKです。

config/environments/development.rb
Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  (省略)...

  # mailer setting
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end

2. root_urlの指定
1番で指定したhttp://localhost:3000/にアクセスした際に表示されるページを指定します。
現状ページは1つも作っていないため、先に追加します。

Pagesコントローラーと、indexページとshowページを追加してみます。

$ rails g controller Pages index show

routes.rbに以下を指定します。

config/routes.rb
Rails.application.routes.draw do
  root 'pages#index'
  get 'pages/show'
  (省略)...
end

3. flashメッセージの設定
ログインした時などに上の方に「ログインしました」みたいなメッセージが出るようにします。
以下のファイルの<body>タグのすぐ下に指定されたタグを挿入します。

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html> 
 <head>
  <title>DeviseRails5</title>
  <%= csrf_meta_tags %>

  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
 </head>
 <body>
  <p class="notice"><%= notice %></p>
  <p class="alert"><%= alert %></p>

  <%= yield %>

 </body> 
</html>

4. DeviseのViewを生成
Deviseの導入で追加されるViewは、以下のコマンドを実行しなければデザインを変更できないので、デザインをカスタマイズするためにも実行します。

$ rails g devise:views

すると以下の様なファイルが生成されます。

app/views/devise/shared/_links.html.erb (リンク用パーシャル)
app/views/devise/confirmations/new.html.erb (認証メールの再送信画面)
app/views/devise/passwords/edit.html.erb (パスワード変更画面)
app/views/devise/passwords/new.html.erb (パスワードを忘れた際、メールを送る画面)
app/views/devise/registrations/edit.html.erb (ユーザー情報変更画面)
app/views/devise/registrations/new.html.erb (ユーザー登録画面)
app/views/devise/sessions/new.html.erb (ログイン画面)
app/views/devise/unlocks/new.html.erb (ロック解除メール再送信画面)
app/views/devise/mailer/confirmation_instructions.html.erb (メール用アカウント認証文)
app/views/devise/mailer/password_change.html.erb (メール用パスワード変更完了文)
app/views/devise/mailer/reset_password_instructions.html.erb (メール用パスワードリセット文)
app/views/devise/mailer/unlock_instructions.html.erb (メール用ロック解除文)

3. Userモデルの設定

1. Userモデルの作成

以下を実行。

$ rails g devise User

マイグレーションファイルができます。
デフォルトではこんな感じになってます。

db/migrate/20161112121754_devise_create_users.rb
class DeviseCreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer  :sign_in_count, default: 0, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at


      t.timestamps null: false
    end

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    # add_index :users, :confirmation_token,   unique: true
    # add_index :users, :unlock_token,         unique: true
  end
end

Userモデルはこんな感じになっています。
デフォルトではdatabase_authenticatableregisterablerecoverablerememberabletrackablevalidatableが使えるようになっています。

app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

2. deviseモジュール概要

各モジュールについて以下に紹介します。

機能 概要
database_authenticatable サインイン時にユーザーの正当性を検証するためにパスワードを暗号化してDBに登録します。認証方法としてはPOSTリクエストかHTTP Basic認証が使えます。
registerable 登録処理を通してユーザーをサインアップします。また、ユーザーに自身のアカウントを編集したり削除することを許可します。
recoverable パスワードをリセットし、それを通知します。
rememberable 保存されたcookieから、ユーザーを記憶するためのトークンを生成・削除します。
trackable サインイン回数や、サインイン時間、IPアドレスを記録します。
validatable Emailやパスワードのバリデーションを提供します。独自に定義したバリデーションを追加することもできます。
confirmable メールに記載されているURLをクリックして本登録を完了する、といったよくある登録方式を提供します。また、サインイン中にアカウントが認証済みかどうかを検証します。
lockable 一定回数サインインを失敗するとアカウントをロックします。ロック解除にはメールによる解除か、一定時間経つと解除するといった方法があります。
timeoutable 一定時間活動していないアカウントのセッションを破棄します。
omniauthable intridea/omniauthをサポートします。TwitterやFacebookなどの認証を追加したい場合はこれを使用します。

3. Userモデルの編集

今回はデフォルトではないものも触ってみたいと思うので全部入れてみます。
Twitter認証を使うのでTwitterを指定しています。

app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable, :lockable, :timeoutable, :omniauthable, omniauth_providers: [:twitter]
end

4. マイグレーションファイルの編集

上に合わせて使用モジュールに対応する部分のコメントアウトを外します。今回は全部使うので全部外します。

db/migrate/20161112121754_devise_create_users.rb
class DeviseCreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer  :sign_in_count, default: 0, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## Confirmable
      t.string   :confirmation_token
      t.datetime :confirmed_at
      t.datetime :confirmation_sent_at
      t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      t.string   :unlock_token # Only if unlock strategy is :email or :both
      t.datetime :locked_at


      t.timestamps null: false
    end

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    add_index :users, :confirmation_token,   unique: true
    add_index :users, :unlock_token,         unique: true
  end
end

5. omniauth-twitter用カラムの追加

ついでにomniauth-twitterで使うprovideruid、それとTwitter認証の場合はアカウント名を保存しておきたいのでusernameもUserテーブルに追加します。

$ rails g migration add_columns_to_users provider uid username

以下のようなマイグレーションファイルができます。

db/migrate/20161112122634_add_columns_to_users.rb
class AddColumnsToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :provider, :string
    add_column :users, :uid, :string
    add_column :users, :username, :string
  end
end

ここまで出来たら以下を実行します。

$ rake db:migrate

4. viewの編集

以下のファイルを編集して、ページ上部にメニューが出るようにします。
user_signed_in?はdeviseのHelperメソッドです。
ログインしているかしてないかで上部のメニューの表示が変わるようになります。
current_userで現在サインインしているユーザーの情報を取得できます。

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
    <head>
        <title>DeviseRails5</title>
        <%= csrf_meta_tags %>

        <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
        <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
    </head>

    <body>
        <header>
            <nav>
                <% if user_signed_in? %>
                <strong><%= link_to current_user.username, pages_show_path %></strong>
                <%= link_to 'プロフィール変更', edit_user_registration_path %>
                <%= link_to 'ログアウト', destroy_user_session_path, method: :delete %>
            <% else %>
                <%= link_to 'サインアップ', new_user_registration_path %>
                <%= link_to 'ログイン', new_user_session_path %>
                <% end %>
            </nav>
        </header>

        <p class="notice"><%= notice %></p>
        <p class="alert"><%= alert %></p>

        <%= yield %>
    </body>
</html>

以下の2ページも修正。
indexの方がトップページ、showの方がログインしているユーザー用のページになる予定です。

app/views/pages/index.html.erb
<h1>ようこそ</h1>
<p>トップページです。</p>
app/views/pages/show.html.erb
<h1>こんにちは、<%= current_user.username %>さん</h1>
<p>ユーザー用ページです。</p>

サーバーを立ち上げて、「サインアップ」を押下すると、app/models/user.rbomniauthableを設定しているのに何の設定もしていないので現状ではエラーになります。
エラー.png

omniauthableを設定していない場合はサインアップページが表示されます。

Twitterで認証する

1. 設定

1. Twitter Developerの登録

Twitter Developerにアクセスし、Create New Appをクリックし(ツイッターにログインしてないとボタンが出ません)、情報を適当の入力にします。
Twitterアプリ登録.png

作成したプロジェクトを開き、Settingsタブの下の方のAllow this application to be used to Sign in with Twitterにチェックが入っていることを確認します。

2. 設定ファイルの編集

Keys and Access Tokensタブを開き、Consumer Key (API Key)Consumer Secret (API Secret)を以下の該当箇所にコピーして貼り付けます。

config/initializers/devise.rb
Devise.setup do |config|
  # The secret key used by Devise. Devise uses this key to generate
  (省略)...
  config.omniauth :twitter, "API Key", "API Secret"
end

2. 動作確認

サーバーを立ち上げてサインアップページの下の方にあるSign in with Twitterというリンクをクリックします。

すると以下の様な画面が開くので連携アプリを認証をクリックします。
連携アプリの認証.png

こんな画面が出るはずです。
スクリーンショット 2015-02-18 23.52.20.png

3. コールバック用コントローラーの作成

Twitter認証後適切に画面が遷移するように以下を実行してコントローラーを作ります。

$ rails g controller omniauth_callbacks

作成したコントローラーの中身を以下のように修正します。
継承するのがDevise::OmniauthCallbacksControllerになっていることに注意です。
omniauth.authという環境変数に認証に関する情報が入っています。
その情報を使ってユーザーが登録されているかを検証し、登録してる場合はログイン、登録されてない場合は登録用ページに遷移します。

app/controllers/omniauth_callbacks_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
    def twitter
        @user = User.from_omniauth(request.env["omniauth.auth"].except("extra"))

        if @user.persisted?
            sign_in_and_redirect @user
        else
            session["devise.user_attributes"] = @user.attributes
            redirect_to new_user_registration_url
        end
    end
end

ちなみにomniauth.authの中にはこんなものが入ってます。(一部の値は適当に変えてあります。)

{"provider"=>"twitter", "uid"=>"0123456789", "info"=>{"nickname"=>"manycicadas", "name"=>"芭蕉", "location"=>"関東", "image"=>"http://pbs.twimg.com/profile_images/483964583371997185/2ZqzhzKV_normal.png", "description"=>"JavaEE/Ruby(Rails)/HTML/CSS/JavaScript/Raspberry Pi などなどが好き。", "urls"=>{"Website"=>nil, "Twitter"=>"https://twitter.com/manycicadas"}}, "credentials"=>{"token"=>"0123456789-hQywfs78sQ9NnwpSkwiejf2Ij74sut7hKjEsF9", "secret"=>"sijIYUsiJslOhiwkYukshKKJG6skWbhbXCYji3sabla3O1"}}

Userモデルにself.from_omniauthself.new_with_sessionを作ります。
self.from_omniauthではuidとproviderで検索してあったらそれを、無かったらレコードを作ります。
self.new_with_sessionについては、もしこのメソッドを追加しておかなければ、Twitter認証後サインアップページで登録を行っても、認証情報として取ってきたuidやproviderなどが登録されません。それらが登録されないのでTwitterで認証しても登録されてないユーザーとして毎回サインアップページに飛ばされます。

app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable, :lockable, :timeoutable, :omniauthable, omniauth_providers: [:twitter]

  def self.from_omniauth(auth)
    find_or_create_by(provider: auth["provider"], uid: auth["uid"]) do |user|
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.username = auth["info"]["nickname"]
    end
  end

  def self.new_with_session(params, session)
    if session["devise.user_attributes"]
      new(session["devise.user_attributes"]) do |user|
        user.attributes = params
      end
    else
      super
    end
  end
end

以下ファイルを編集して、コールバック用のコントローラーとしてさっき作ったコントローラーが呼ばれるようにします。これを書かないとdevise側のコントローラーが呼ばれます。

config/routes.rb
Rails.application.routes.draw do
  devise_for :users, controllers: { :omniauth_callbacks => "omniauth_callbacks" }
  root 'pages#index'
  get 'pages/show'
  (省略)...
end

これでTwitter認証ができるようになりました。
初回、Twitter認証を行うと、サインアップページに飛ばされ、そこでメールアドレスやパスワードを入力して登録するとユーザー情報が登録されます。
今回はcomfirmable機能を入れているので、登録したら確認メッセージを送ったとのメッセージが出て、そのままログインすることはできません。
この機能を入れてなかった場合、登録すると即ログインします。

アカウント登録確認メールを送る

1. comfirmable概要

多くの登録系サイトで採用されている、登録すると仮登録状態になり、届いたメールのリンクをクリックするとログイン可能になるという仕組みを追加できるのがcomfirmableです。
今回はGmailのアカウントを使って実際にメールが届くように設定します。

2. ログを見る

サインアップ画面からEmailやパスワードを入力して登録すると、ログに以下のような内容が出力されます。
現状何も設定してないので、送信元アドレスなどがデフォルトであることが分かります。

log/deployments.log
Devise::Mailer#confirmation_instructions: processed outbound mail in 715.7ms
Sent mail to test@example.com (51.1ms)
Date: Sat, 12 Nov 2016 22:26:18 +0900
From: please-change-me-at-config-initializers-devise@example.com
Reply-To: please-change-me-at-config-initializers-devise@example.com
To: test@example.com
Message-ID: <5827187aa0893_104ff3fcd39297f34991c@YukihonoiMac-8.local.mail>
Subject: Confirmation instructions
Mime-Version: 1.0
Content-Type: text/html;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

<p>Welcome test@example.com!</p>

<p>You can confirm your account email through the link below:</p>

<p><a href="http://localhost:3000/users/confirmation?confirmation_token=ZaPGWtxbTzo_3eJxvzm9">Confirm my account</a></p>

3. メールが実際に届くようにする

1. 設定ファイルの編集

今回はgmailを使うのでメールアドレスにはgmailを設定します。

config/initializers/devise.rb
Devise.setup do |config|
  (省略)...
  # mail setting
  config.mailer_sender = "メールアドレス"
end

gmailの場合はGメールアドレスとGメールパスワードの部分を自分のアカウントのものに変更します。

config/environments/development.rb
Rails.application.configure do
  # default url
  config.action_mailer.default_url_options = {  host: 'localhost', port: 3000 }
  # mail setting
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :address => "smtp.gmail.com",
    :port => 587,
    :user_name => "Gメールアドレス",
    :password => "Gメールパスワード",
    :authentication => :plain,
    :enable_starttls_auto => true
  }
end

2. Gmailの設定

1. とりあえず試したい場合

デフォルトでは安全性の低いアプリケーションからGmailへのアクセスが制限されています。
よってその制限を解除することで動くようにできます。
ただ、安全性の低いアプリからのアクセスを許可するということはセキュリティ的にはいまいちなのであくまで動作確認ように利用することをおすすめします。
安全性の低いアプリがアカウントにアクセスするのを許可する安全性の低いアプリを許可というリンクをクリックして、以下のように設定します。
スクリーンショット 2015-02-21 11.49.19.png

2. 2段階認証がオンの場合

2段階認証をオンにしている場合、1の設定はできないはずなのでこちらをやってください。
また、1のセキュリティ的にイマイチな方をやりたくない方もこの際2段階認証をオンにしてこの設定をやってください。

アカウントへのアクセスとセキュリティ設定の管理を開きます。
2段階認証がオフの場合は2段階認証プロセスから2段階認証の設定をしてください。(2 段階認証プロセスを有効にする)
2段階認証設定を行っている場合はアプリパスワードを開きます。
パスワードとログイン方法.png

端末を選択アプリを選択で適切なものを選びます。
私は端末を選択ではMacを、アプリを選択でその他(名前を入力)を選択して登録しました。
アプリパスワード.png

パスワードが生成されます。
2段階認証パスワード.png

生成されたパスワードを、1の設定の:password => "Gメールパスワード",のGメールのパスワードの部分に設定します。

3. 届いたメールを確認

これでアプリ側からサインアップすると、以下の様なメールが届くようになります。Confirm my accountをクリックするログイン画面からログインが可能になります。
承認メール.png

メールで送られる文章は以下のファイルを編集することで可能です。
app/views/devise/confirmation_instructions.html.erb

アカウントをロックする

1. lockable概要

アカウントの認証を一定回数間違うと、アカウントをロックするようにする機能です。

2. 設定

1. 設定ファイルの編集

以下ファイルを修正して、アカウントの認証を5回失敗します。

config/initializers/devise.rb
Devise.setup do |config|
    (省略)...
    # lock sessings
    config.unlock_strategy = :email
    config.maximum_attempts = 4
end

するとアカウントがロックされてこのようなメールが届きます。
アンロックメール.png

メールの中身はapp/views/devise/mailer/unlock_instructions.rbファイルを修正すれば変わります。

2. 設定値について

  • lock_strategy(ロック方法)
属性 説明
:failed_attempts 失敗回数によってロック。
:none ロックしない。
  • unlock_strategy(ロック解除方法)
属性 説明
:time 指定時間でロックを解除する。
:email メールでロックを解除する。
:both :timeと:emailの両方。
:none 解除させない。

:noneを指定した場合、ユーザーのレコードのlocked_atカラムをnilにアップデートしたらロックが解除できます。

  • unlock_in(ロック解除時間)

2時間で解除するならconfig.unlock_in = 2.hoursといった具合に指定。

  • unlock_keys

アカウントをロックまたは解除するときに使用するキーを定義するらしいです。
config.unlock_keys = [:username]という感じで指定できます。

  • maximum_attempts(失敗可能回数)

アカウントの認証を失敗して良い回数を指定します。
config.maximum_attempts = 4と指定した場合、4回目までは失敗しても大丈夫ですが、5回目を失敗した時点でアカウントがロックされます。

セッションをタイムアウトする

1. timeoutable概要

一定時間活動がない場合にセッションをタイムアウトさせるのがtimeoutableです。

2. 設定

以下ファイルを修正するとタイムアウトまでの時間を指定できます。
以下の場合だと3分後にセッションがタイムアウトします。
デフォルトは30分だそうです。

config/initializers/devise.rb
Devise.setup do |config|
    (省略)...
    # timeout setting
    config.timeout_in = 3.minutes
end

その他の設定

1. ログイン後のページを変更する

ログインすると、デフォルトではroot_urlに飛ばされます。
これをapp/views/pages/show.html.erbになるように修正します。
after_sign_in_path_forメソッドを追加します。ここにログイン後に遷移したいページを指定します。
あとsign_in_requiredも追加します。showページはログインしているユーザーだけにアクセスさせ、ログインしてない場合はログインページに遷移させます。

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  (省略)...
    def after_sign_in_path_for(resource)
        pages_show_path
    end

    private
        def sign_in_required
            redirect_to new_user_session_url unless user_signed_in?
        end
end

Pagesコントローラーにbefore_actionを追加します。

app/controllers/pages_controller.rb
class PagesController < ApplicationController
  before_action :sign_in_required, only: [:show]
  (省略)...
end

これでログイン後showページに遷移するようになります。

2. サインアップする際に登録するパラメーターを増やす

ユーザーを登録するときにデフォルトではEmailとパスワードだけですが、
ユーザー名も登録させたい、などの場合があると思います。

まずはサインアップページにユーザー名を入力するエリアを追加します。
ユーザーのプロフィール変更ページ(views/devise/registrations/edit.html.erb)にも同様に追加しときます。

views/devise/registrations/new.html.erb
<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <!-- 省略 -->

  <div class="field">
    <%= f.label :username %><br />
    <%= f.text_field :username %>
  </div>

  <!-- 省略 -->
<% end %>

<%= render "devise/shared/links" %>

次にApplicationControllerに以下を追加します。
テンプレートを変えて、ユーザー名を入力するようにしただけでは実際に登録されないからです。
詳しくはstrong_parametersについて調べてください。
簡単に言えばよく分からんパラメーターは渡せないようになってるので渡せるようにします。

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :configure_permitted_parameters, if: :devise_controller?

  # 省略

  protected
    def configure_permitted_parameters
      devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
      devise_parameter_sanitizer.permit(:account_update, keys: [:username])
    end
end

最後に

作ったプロジェクト全体は以下です。
cigalecigales/devise_rails5