Clearance는 Thoughtbot 팀이 만든 이메일과 비밀번호 기반의 간단한 인증 시스템입니다. 독단적인 기본 설정을 가지고 있지만, 필요에 따라 쉽게 재정의(오버라이드)할 수 있도록 설계되었습니다. 현재도 꾸준히 유지보수가 이루어지고 있으며, GitHub에서 관련 소식을 확인할 수 있습니다.
이 튜토리얼에서는 Rails 애플리케이션에 Clearance를 통합하는 방법을 알아보겠습니다. 설명을 위해 작은 규모의 애플리케이션을 활용할 예정입니다. 그럼 시작해 보겠습니다!
시작하기
먼저 Rails 애플리케이션을 생성합니다. 이 튜토리얼에서는 애플리케이션 이름을 tutsplus-clearance로 지정하겠습니다.
rails new tutsplus-clearance -T
이 명령어 하나로 앱 생성이 완료됩니다.
애플리케이션의 외관을 보기 좋게 만들기 위해 Bootstrap이 필요합니다. Gemfile에 Bootstrap 젬을 추가하세요.
#Gemfile ... gem 'bootstrap-sass'
그리고 bundle install을 실행하여 젬을 설치합니다.
이제 application.scss 파일을 아래와 같이 수정합니다.
#app/assets/stylesheets/application.scss @import 'bootstrap-sprockets'; @import 'bootstrap';
Clearance 설치 및 설정
Gemfile을 열어 Clearance 젬을 추가합니다.
#Gemfile gem 'clearance'
젬을 설치합니다.
bundle install
설치가 끝났다면 다음 제너레이터 명령어를 실행하여 Clearance를 애플리케이션에 적용합니다.
rails generate clearance:install
명령어를 실행하면 터미널에 아래와 비슷한 출력 결과가 나타납니다.
create config/initializers/clearance.rb
insert app/controllers/application_controller.rb
create app/models/user.rb
create db/migrate/20161115101323_create_users.rb
*******************************************************************************
Next steps:
1. Configure the mailer to create full URLs in emails:
# config/environments/{development,test}.rb
config.action_mailer.default_url_options = { host: 'localhost:3000' }
In production it should be your app's domain name.
2. Display user session and flashes. For example, in your application layout:
<% if signed_in? %>
Signed in as: <%= current_user.email %>
<%= button_to 'Sign out', sign_out_path, method: :delete %>
<% else %>
<%= link_to 'Sign in', sign_in_path %>
<% end %>
<div id="flash">
<% flash.each do |key, value| %>
<div class="flash <%= key %>"><%= value %></div>
<% end %>
</div>
3. Migrate:
rake db:migrate
*******************************************************************************명령어를 실행하면 애플리케이션에 여러 파일이 생성됩니다. 그중 하나가 config/initializers 디렉터리에 위치한 clearance.rb입니다. 또한 User 모델이 생성되며, 함께 만들어진 마이그레이션 파일은 다음과 같습니다.
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.timestamps null: false
t.string :email, null: false
t.string :encrypted_password, limit: 128, null: false
t.string :confirmation_token, limit: 128
t.string :remember_token, limit: 128, null: false
end
add_index :users, :email
add_index :users, :remember_token
end
end출력된 안내에 따르면, 가장 먼저 환경 설정 파일을 수정해야 합니다. config/environments/development.rb 파일로 이동한 후, 아래 코드를 end 바로 위에 추가하세요.
...
config.action_mailer.default_url_options = { host: 'localhost:3000' }
end다음으로 config/initializers/clearance.rb 파일을 열어 발신자 이메일 주소를 기본값에서 원하는 주소로 변경합니다. 파일을 열면 다음과 같은 내용이 보일 것입니다.
#config/initializers/clearance.rb Clearance.configure do |config| config.mailer_sender = "reply@example.com" end
아래 코드 스니펫을 붙여넣고 용도에 맞게 설정하면 기본 구성을 자유롭게 재정의할 수 있습니다.
#config/initializers/clearance.rb
Clearance.configure do |config|
config.allow_sign_up = true
config.cookie_domain = ".example.com"
config.cookie_expiration = lambda { |cookies| 1.year.from_now.utc }
config.cookie_name = "remember_token"
config.cookie_path = "/"
config.routes = true
config.httponly = false
config.mailer_sender = "reply@example.com"
config.password_strategy = Clearance::PasswordStrategies::BCrypt
config.redirect_url = "/"
config.secure_cookie = false
config.sign_in_guards = []
config.user_model = User
end이제 데이터베이스 마이그레이션을 실행합니다.
rake db:migrate
PagesController를 열고 index 액션을 추가합니다.
#app/controllers/pages_controller.rb class PagesController < ApplicationController def index end end
다음으로 방금 만든 index 액션의 뷰를 생성합니다. 아래 코드 스니펫을 추가하세요.
#app/views/pages/index.html.erb <h1>Tutsplus Clearance</h1> <p>Welcome to our Clearance Page.</p>
라우트를 다음과 같이 수정합니다.
#config/routes.rb Rails.application.routes.draw do root to: "pages#index" end
layouts 디렉터리 안에 _navigation.html.erb라는 이름의 파셜(partial) 파일을 생성합니다. 이 파일은 애플리케이션의 네비게이션과 관련된 모든 처리를 담당하게 됩니다.
아래 코드를 붙여넣고 저장하세요.
#app/views/layouts/_navigation.html.erb
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<%= link_to 'Tutsplus-Clearance', root_path, class: 'navbar-brand' %>
</div>
<div id="navbar">
<% if signed_in? %>
<ul class="nav navbar-nav">
<li><%= link_to 'Add Page', new_page_path %></li>
</ul>
<% end %>
<ul class="nav navbar-nav pull-right">
<% if signed_in? %>
<li><span><%= current_user.email %></span></li>
<li><%= link_to 'Sign out', sign_out_path, method: :delete %></li>
<% else %>
<li><%= link_to 'Sign in', sign_in_path %></li>
<% end %>
</ul>
</div>
</div>
</nav>
<div class="container">
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>">
<%= value %>
</div>
<% end %>
</div>접근 제한 설정
Clearance를 사용하면 애플리케이션 내 특정 페이지에 대해 로그인한 사용자만 접근할 수 있도록 제한할 수 있습니다. 어떻게 구현되는지 살펴보겠습니다.
app/views/pages 디렉터리에 new 액션용 뷰 파일을 생성하고, 파일 이름은 new.html.erb로 지정합니다. 그리고 아래 코드를 붙여넣으세요.
#app/views/pages/new.html.erb <h1>Restricted Page</h1> <p>This page is restricted to authenticated users, if you can see this it means you are a superstar!</p>
이제 config/routes.rb에 아래 라인을 추가해야 합니다.
#config/routes.rb ... resources :pages, only: :new ...
마지막으로 PagesController를 아래와 같이 수정합니다.
#apps/controllers/pages_controller.rb class PagesController < ApplicationController before_action :require_login, only: [:new] def index end def new end end
위 코드에서는 Clearance가 제공하는 헬퍼 메서드인 require_login을 사용해 new 액션에 대한 접근을 제한했습니다. 실제 동작을 확인하려면 터미널에서 rails server를 실행해 Rails 서버를 시작한 뒤, 브라우저에서 https://locahost:3000/pages/new로 접속해 보세요. 로그인 페이지로 리디렉션되는 것을 확인할 수 있습니다.
또한 Clearance는 접근 제어에 활용할 수 있는 라우팅 제약 조건(routing constraints)도 제공합니다.
#config/routes.rb
Rails.application.routes.draw do
constraints Clearance::Constraints::SignedOut.new do
root to: 'pages#index'
end
constraints Clearance::Constraints::SignedIn.new do
root to: "pages#new', as: :signed_in_root
end
end위 코드처럼 인증된 사용자를 위한 별도의 라우트를 구성할 수 있습니다.
Clearance 기본 설정 재정의하기
Clearance를 사용하기 시작하면 화면에는 보이지 않지만 수많은 작업이 백그라운드에서 진행됩니다. 애플리케이션의 요구 사항에 따라 이러한 부분을 다르게 커스터마이징해야 할 때가 올 수 있습니다. Clearance는 자체적으로 제공하는 기본 설정을 손쉽게 재정의할 수 있도록 지원합니다.
Clearance의 라우트를 오버라이드(또는 생성)하려면 터미널에서 다음 명령어를 실행합니다.
rails generate clearance:routes
실행 후 라우트 파일은 아래와 같이 변경됩니다.
#config/routes.rb
Rails.application.routes.draw do
resources :passwords, controller: "clearance/passwords", only: [:create, :new]
resource :session, controller: "clearance/sessions", only: [:create]
resources :users, controller: "clearance/users", only: [:create] do
resource :password,
controller: "clearance/passwords",
only: [:create, :edit, :update]
end
get "/sign_in" => "clearance/sessions#new", as: "sign_in"
delete "/sign_out" => "clearance/sessions#destroy", as: "sign_out"
get "/sign_up" => "clearance/users#new", as: "sign_up"
root to: "pages#index"
resources :pages, only: :new
end이 명령어는 config/initializers/clearance.rb 파일에서 config.routes 설정을 false로 변경합니다. 즉, 방금 생성된 커스텀 라우트 파일이 사용된다는 의미입니다.
뷰 파일을 수정하기 위해 생성하려면 다음 명령어를 실행합니다.
rails generate clearance:views
생성되는 파일 중 일부는 다음과 같습니다.
app/views/passwords/create.html.erb app/views/passwords/edit.html.erb app/views/passwords/new.html.erb app/views/sessions/_form.html.erb app/views/sessions/new.html.erb app/views/users/_form.html.erb app/views/users/new.html.erb config/locales/clearance.en.yml
이 과정에서 app/views/layouts/application.html.erb 파일을 덮어쓸지 묻는 프롬프트가 터미널에 나타날 수 있습니다. 원하는 옵션을 선택하면 됩니다.
레이아웃 설정
기본적으로 Clearance는 애플리케이션의 기본 레이아웃을 사용합니다. Clearance가 자체 뷰를 렌더링할 때 다른 레이아웃을 사용하길 원한다면, 이니셜라이저에서 레이아웃을 간단히 지정할 수 있습니다.
Clearance::PasswordsController.layout "my_passwords_layout" Clearance::SessionsController.layout "my_sessions_layout" Clearance::UsersController.layout "my_admin_layout"
헬퍼 메서드
Clearance는 controllers, views, helpers에서 사용할 수 있는 다양한 헬퍼 메서드를 제공합니다. 대표적인 메서드로 signed_in?, signed_out?, current_user 등이 있습니다. 예시는 다음과 같습니다.
<% if signed_in? %> <%= current_user.email %> <%= button_to "Sign out", sign_out_path, method: :delete %> <% else %> <%= link_to "Sign in", sign_in_path %> <% end %>
마무리
Clearance는 인증 기능 구현에 필요한 다양한 기능을 제공하므로, 다음 프로젝트에서 꼭 한번 활용해 보시기 바랍니다. 더 자세한 내용은 GitHub 페이지를 참고하면 좋습니다.