루비 온 레일즈에서 devise gem 없이 로그인 기능 구현하기 2 (How to build authentication system without devise gem in Ruby on Rails)



## 루비 온 레일즈에서 devise gem 없이 로그인 기능 구현하기 2 (How to build authentication system without devise gem in Ruby on Rails)

##### 회원가입이 되었으니 로그인 기능을 만들어보도록 하겠습니다. 혹시나 회원가입 파트가 필요한 분은 아래 링크에 들어가 확인해보시기 바랍니다.

[루비 온 레일즈에서 devise gem 없이 로그인 기능 구현하기 - 회원가입](https://ghkdgh2365.blogspot.com/2020/03/devise-gem-how-to-build-authentication.html)

추가적으로 회원가입 후 축하 이메일 기능을 구현하고 싶은 분은 아래 링크에 들어가 확인해보시기 바랍니다.

[루비 온 레일즈 액션 메일러를 이용해 메일 기능 구현하기](https://ghkdgh2365.blogspot.com/2020/05/creating-mail-function-by-using-ruby-on.html)

---

#### 2. 쿠키를 이용한 로그인

먼저 로그인 화면이 필요하겠죠? 먼저 `controllers` 폴더에 `cookie_controller.rb` 파일을 만들어줍니다. 그 다음 아래와 같이 작성합니다.

```
class CookieController < ApplicationController
  def new
  end
end
```

그 다음 `views` 폴더에 `cookie` 라는 폴더를 만들고 그 안에 `new.html.erb` 라는 파일을 만듭니다. 그 다음 아래와 같은 코드를 작성합니다. 회원가입과 비슷한 형태로 간단히 만들었습니다.

```
<h2>로그인</h2>

<%= form_with(url: "/cookie/sign_in)") do |f|%>
    <%= f.label :email %>
    <%= f.text_field :email %>

    <%= f.label :password %>
    <%= f.password_field :password %>

    <%= f.submit "로그인" %>
<% end %>
```

그 다음 `routes.rb` 파일에 가서 아래 같이 입력해줍니다.

```
get 'cookie/new'
```

이제 `localhost:3000/cookie/new` 로 브라우저에 들어가보면 로그인 화면이 보입니다. 만약 안보인다면 코드를 다시 한 번 보시고, 서버가 켜졌는지 확인해보세요.(만약 서버가 꺼져있다면, 커맨드 창에 `rails s` 를 입력해주시면 서버가 켜집니다.) 편의를 위해 로그인 화면으로 가는 링크를 만듭니다.

```
<h2> Hello World ! </h2>

<%= link_to "로그인", cookie_new_path %>
<hr/>
<%= link_to "회원가입", new_user_path %>
```

그 다음, 로그인 버튼을 눌렀을 때 sign_in을 해줄 sign_in action 과 route 설정을 해줄 것입니다. 다시 `cookie_controller.rb` 에 가서 아래와 같이 입력합니다. 로그인 화면에서 로그인 버튼을 누르면 email과 password가 parameter로 전송이 됩니다. 그 값으로 Email이 존재하는지, password가 일치하는지를 확인합니다.

```
class CookieController < ApplicationController
  def new
  end

  def create
    if params[:email].present? && params[:password].present?
      user = User.find_by(email: params[:email])
      if user.present?
        if user.authenticate(params[:password])
          cookies[:email] = user.email
          cookies[:password] = user.password_digest
          flash[:notice] = "로그인 성공"
          redirect_to '/home/index'
        else
          flash[:notice] = "잘못된 비밀번호 입니다. 다시 확인해주세요."
        end
      else
        flash[:notice] = "잘못된 이메일입니다. 다시 확인해주세요."
      end
    else
      flash[:notice] = "이메일, 패스워드 모두 입력해주세요."
    end
    redirect_to cookie_new_path
  end
end
```

그 다음 `routes.rb` 에 다음과 같이 작성합니다.

```
post 'cookie/sign_in', to: 'cookie#create'
```

그리고 로그인을 눌렀을 때 어떤 결과가 나오는지 flash로 받아보기 위해 `views/layouts/application.html.erb`  에 아래와 같이 코드를 입력합니다.

```
<!--DOCTYPE html-->
<html>
  <head>
    <title>Devise gem 없이 로그인 구현하기</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

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

  <body>
    <% if flash[:notice] %>
      <div class="notice"><%= flash[:notice] %></div>
    <% end %>
    <%= yield %>
  </body>
</html>

```

이제 로그인이 되었는지, 안되었는지 확인하기 위해 `controllers` 폴더에 `application_controller.rb` 파일에 아래와 같은 코드를 입력합니다.

```
class ApplicationController < ActionController::Base
  helper_method :current_user
  def current_user
    @current_user ||= User.find_by(email: cookies[:email], password_digest: cookies[:password])
  end
end
```

마지막으로 `views` 폴더에 `home` 폴더에 `index.html.erb` 파일에 아래와 같이 코드를 입력합니다. 로그인이 되었다면 로그아웃 버튼이 보일 것이고, 로그인이 되지 않았다면 로그인 버튼이 보일 것입니다.

```
<h2> Hello World ! </h2>

<% if current_user.present? %>
  <a href="#"> 로그아웃 </a>
<% else %>
  <%= link_to "로그인", cookie_new_path %>
<% end %>
<hr/>
<%= link_to "회원가입", new_user_path %>
```

다시 짧게 설명을 드리자면, cookie/sign_in 이라는 주소를 POST 방법으로 서버에 요청하면 cookie 컨트롤러의 create 액션이 작동하게 되며 그 안에서 email과 password 를 받아 판별하고 로그인이 되었을 시에 current_user 액션에서 email 쿠키를 찾아 로그아웃이라는 것을 보여줄 지 안 보여줄지 판가름하는 것입니다. 

참고로 cookie가 브라우저에 저장되었는지 안되었는지는 크롬 브라우저의 경우에는 키보드 `F12` 를 누르고 Application 탭에 들어가 왼쪽 Cookies 라는 곳에서 확인할 수 있습니다. 아래 이미지를 참고하세요.

<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYjh9O-XXCJ8s2PZfleTh5IfHeDPQJbuaWiUmvIPCJuDxnGxM2bU7bhM_8RvCEhhbdy0lL64qDrKyWGooOKGlr5LNDrNbT1v6n6jkeXctj11TdUs6UFZk8WrNODqUVSp4nzCGNMYoLMUQS/s1600/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA+2020-07-20+%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE+10.44.45.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="406" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYjh9O-XXCJ8s2PZfleTh5IfHeDPQJbuaWiUmvIPCJuDxnGxM2bU7bhM_8RvCEhhbdy0lL64qDrKyWGooOKGlr5LNDrNbT1v6n6jkeXctj11TdUs6UFZk8WrNODqUVSp4nzCGNMYoLMUQS/s1600/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA+2020-07-20+%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE+10.44.45.png" /></a></div>

로그아웃은 간단합니다. 로그인과 유사하게 컨트롤러에 액션을 만들고, route 를 정의한 뒤, path를 호출하면 됩니다. 먼저 `cookie_controller.rb`에 들어가서 아래와 같이 입력합니다.

```
  def destroy
    if current_user.present?
      cookies.delete :email
      cookies.delete :passowrd
      redirect_to cookie_new_path
    end
  end
```

그 다음, `routes.rb` 에 가서 아래 코드를 추가합니다.

```
delete 'cookie/sign_out', to: 'cookie#destroy'
```

그리고 마지막으로 `view/home/index` 에 가서 로그아웃 path와 메소드를 설정해줍니다.

```
<h2> Hello World ! </h2>

<% if current_user.present? %>
  <%= link_to "로그아웃", cookie_sign_out_path, method: :delete %>
<% else %>
  <%= link_to "로그인", cookie_new_path %>
<% end %>
<hr/>
<%= link_to "회원가입", new_user_path %>
```

이제 `/home/index` 에 가서 로그아웃을 클릭하면 로그인 화면으로 이동하고 다시 `home/index`로 가면 로그인이 풀려 있는 것을 확인할 수 있습니다.


댓글

  1. 안녕하세요 선생님 덕에 많은 도움이 되었습니다!
    근데 그대로 구현했을때 자바스크립트
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>

    이 곳에서 에러가 나는데 주석처리 하면 에러가 없어지긴 하더라고요,,
    주석처리 말고의 방법은 없을까요? ㅜㅜ

    답글삭제
    답글
    1. 어떤 에러가 나는지 알 수 있을까요?

      삭제

댓글 쓰기

이 블로그의 인기 게시물

부트스트랩 사용 시 버튼 오른쪽 정렬하는 방법 (How to use float-right for right align in bootstrap)

맥(Mac)에서 MySql 사용 시 Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 오류가 발생하는 경우 해결 방법

HTML, CSS - footer fixed (foot 하단 고정 시키기)