Phoenix 登錄/注冊按鈕

2023-12-18 14:41 更新

我們至今還沒有在頁面上添加登錄/注冊按鈕,這對普通用戶來說非常不友好。

老規(guī)則,先寫測試,我們不再新增,而是加在舊測試中:

diff --git a/test/controllers/session_controller_test.exs b/test/controllers/session_controller_test.exs
index 969662a..98fbb5a 100644
--- a/test/controllers/session_controller_test.exs
+++ b/test/controllers/session_controller_test.exs
@@ -14,6 +14,10 @@ defmodule TvRecipe.SessionControllerTest do
     user_changeset = User.changeset(%User{}, @valid_user_attrs)
     # 插入新用戶
     user = Repo.insert! user_changeset
+    # 未登錄情況下訪問首頁,應(yīng)帶有登錄/注冊文字
+    conn = get conn, Routes.page_path(conn, :index)
+    assert html_response(conn, 200) =~ "登錄"
+    assert html_response(conn, 200) =~ "注冊"
     # 用戶登錄
     conn = post conn, Routes.session_path(conn, :create), session: @valid_user_attrs
     # 顯示“歡迎你”的消息

打開 app.html.eex 文件,添加兩個按鈕:

diff --git a/web/templates/layout/app.html.eex b/web/templates/layout/app.html.eex
index 6c87a08..b13f370 100644
--- a/web/templates/layout/app.html.eex
+++ b/web/templates/layout/app.html.eex
@@ -20,6 +20,9 @@
             <%= if @current_user do %>
               <li><%= link @current_user.username, to: Routes.user_path(@conn, :show, @current_user) %></li>
               <li><%= link "退出", to: Routes.session_path(@conn, :delete, @current_user), method: "delete" %></li>
+            <% else %>
+              <li><%= link "登錄", to: Routes.session_path(@conn, :new) %></li>
+              <li><%= link "注冊", to: Routes.user_path(@conn, :new) %></li>
             <% end %>
           </ul>
         </nav>

運行測試:

mix test
....................................

Finished in 0.8 seconds
36 tests, 0 failures

全部通過。

在進(jìn)入下一章前,我們還有個安全相關(guān)的問題需要略作修改:

diff --git a/web/controllers/session_controller.ex b/web/controllers/session_controller.ex
index 6ac524c..0c2eb0a 100644
--- a/web/controllers/session_controller.ex
+++ b/web/controllers/session_controller.ex
@@ -15,6 +15,7 @@ defmodule TvRecipe.SessionController do
         conn
         |> put_session(:user_id, user.id)
         |> put_flash(:info, "歡迎你")
+        |> configure_session(renew: true)
         |> redirect(to: Routes.page_path(conn, :index))
       # 用戶存在,但密碼錯誤
       user ->
diff --git a/web/controllers/user_controller.ex b/web/controllers/user_controller.ex
index 8d8a6f5..8b9b38b 100644
--- a/web/controllers/user_controller.ex
+++ b/web/controllers/user_controller.ex
@@ -21,6 +21,7 @@ defmodule TvRecipe.UserController do
         conn
         |> put_flash(:info, "User created successfully.")
         |> put_session(:user_id, user.id)
+        |> configure_session(renew: true)
         |> redirect(to: Routes.page_path(conn, :index))
       {:error, changeset} ->
         render(conn, "new.html", changeset: changeset)

我們在 session_controller.exuser_controller.ex 兩個文件中加入了 configure_session(renew: true),用于預(yù)防 session fixation 攻擊。

另外,本著 DRY 的原則,我們可以將登錄的邏輯合并到 auth.ex 文件中:

diff --git a/web/controllers/auth.ex b/web/controllers/auth.ex
index 994112d..e298b68 100644
--- a/web/controllers/auth.ex
+++ b/web/controllers/auth.ex
@@ -15,4 +15,10 @@ defmodule TvRecipeWeb.Auth do
     assign(conn, :current_user, user)
   end

+  def login(conn, user) do
+    conn
+    |> put_session(:user_id, user.id)
+    |> configure_session(renew: true)
+  end
+
 end

diff --git a/web/controllers/session_controller.ex b/web/controllers/session_controller.ex
index 0c2eb0a..6f29ce0 100644
--- a/web/controllers/session_controller.ex
+++ b/web/controllers/session_controller.ex
@@ -13,9 +13,8 @@ defmodule TvRecipe.SessionController do
       # 用戶存在,且密碼正確
       user && Comeonin.Bcrypt.checkpw(password, user.password_hash) ->
         conn
-        |> put_session(:user_id, user.id)
         |> put_flash(:info, "歡迎你")
-        |> configure_session(renew: true)
+        |> TvRecipeWeb.Auth.login(user)
         |> redirect(to: Routes.page_path(conn, :index))
       # 用戶存在,但密碼錯誤
       user ->
diff --git a/web/controllers/user_controller.ex b/web/controllers/user_controller.ex
index 8b9b38b..b9234b1 100644
--- a/web/controllers/user_controller.ex
+++ b/web/controllers/user_controller.ex
@@ -20,8 +20,7 @@ defmodule TvRecipe.UserController do
       {:ok, user} ->
         conn
         |> put_flash(:info, "User created successfully.")
-        |> put_session(:user_id, user.id)
-        |> configure_session(renew: true)
+        |> TvRecipeWeb.Auth.login(user)
         |> redirect(to: Routes.page_path(conn, :index))
       {:error, changeset} ->
         render(conn, "new.html", changeset: changeset)


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號