我跟着完整的教程解釋瞭如何處理上下文&通過@chrismccord進行身份驗證/授權......並且我利用了他關於從造船廠博客解除身份驗證的文章:slight_smile:auth for phoenix context和從Adding CMS functions in phoenix contextElixir Phoenix上下文授權(帶和不帶)
根據這一點,在我的情況(CMS是ENR)創建的所有學生需要的註冊程序,將註冊器鏈接到用戶(認證)與自己的會話:學生 - > belongs_to的登記器,註冊人 - > belongs_to用戶,用戶擁有自己的憑證。
resources "/students", StudentController
受保護,這很好。
但是現在我想揭示一些事實:如果我們想讓學生註冊自己,那麼怎麼辦?代碼的外觀如何?
用於自我註冊或自行註冊,而不是由管理員的人做...它會很好。
這裏是我做過什麼,但我總是重定向到認證頁面,結果:「你必須先登錄」。
當管理員已登錄/註冊....他/她可以實現管理任務(創建:同學們,Enrollers,網頁等)這是通過允許:
scope "/enr", HelloWeb.ENR, as: :enr do pipe_through [:browser, :authenticate_user] resources "/admissions", AdmissionController end
爲接納的任務
- 在提及的情況更早如果我們考慮範圍
CMS
或(ENR
)是管理部分,我們希望讓學生通過公共部分註冊自己我不喜歡這條路線: 的
AdmissionController.ex
(環境信息網我的情況)範圍的樣子:defmodule InsWeb.ENR.AdmissionController do use InsWeb, :controller plug :require_existing_enroller plug :authorize_admission when action in [:edit, :update, :delete] alias Ins.ENR alias Ins.ENR.Admission def index(conn, _params) do admissions = ENR.list_admissions() render(conn, "index.html", admissions: admissions) end def new(conn, _params) do changeset = ENR.change_admission(%Admission{}) render(conn, "new.html", changeset: changeset) end def create(conn, %{"admission" => admission_params}) do case ENR.create_admission(conn.assigns.current_enroller, admission_params) do {:ok, admission} -> conn |> put_flash(:info, "Admission created successfully.") |> redirect(to: enr_admission_path(conn, :show, admission)) {:error, %Ecto.Changeset{} = changeset} -> render(conn, "new.html", changeset: changeset) end end def show(conn, %{"id" => id}) do admission = id |> ENR.get_admission!() |> ENR.inc_admission_views() render(conn, "show.html", admission: admission) end def edit(conn, %{"id" => id}) do admission = ENR.get_admission!(id) changeset = ENR.change_admission(admission) render(conn, "edit.html", admission: admission, changeset: changeset) end def update(conn, %{"id" => id, "admission" => admission_params}) do admission = ENR.get_admission!(id) case ENR.update_admission(conn.assigns.admission, admission_params) do {:ok, admission} -> conn |> put_flash(:info, "Admission updated successfully.") |> redirect(to: enr_admission_path(conn, :show, admission)) {:error, %Ecto.Changeset{} = changeset} -> render(conn, "edit.html", admission: admission, changeset: changeset) end end def delete(conn, %{"id" => id}) do admission = ENR.get_admission!(id) {:ok, _admission} = ENR.delete_admission(conn.assigns.admission) conn |> put_flash(:info, "Admission deleted successfully.") |> redirect(to: enr_admission_path(conn, :index)) end defp require_existing_enroller(conn, _) do enroller = ENR.ensure_enroller_exists(conn.assigns.current_user) assign(conn, :current_enroller, enroller) end defp authorize_admission(conn, _) do admission = ENR.get_admission!(conn.params["id"]) if conn.assigns.current_enroller.id == admission.enroller_id do assign(conn, :admission, admission) else conn |> put_flash(:error, "You can't modify that admission page") |> redirect(to: enr_admission_path(conn, :index)) |> halt() end end end
/templates/enr/admission/form.html.eex
<%= form_for @changeset, @action, fn f -> %> <%= if @changeset.action do %> <div class="alert alert-danger"> <p>Oops, something went wrong! Please check the errors below.</p> </div> <% end %> <div class="form-group"> <%= label f, :first_name, class: "control-label" %> <%= text_input f, :first_name, class: "form-control" %> <%= error_tag f, :first_name %> </div> <div class="form-group"> <%= label f, :last_name, class: "control-label" %> <%= text_input f, :last_name, class: "form-control" %> <%= error_tag f, :last_name %> </div> <div class="form-group"> <%= label f, :views, class: "control-label" %> <%= number_input f, :views, class: "form-control" %> <%= error_tag f, :views %> </div> <div class="form-group"> <%= submit "Submit", class: "btn btn-primary" %> </div> <% end %>
/templates/enr/admission/new.html.eex
<h2>New Admission</h2> <%= render "form.html", Map.put(assigns, :action, enr_admission_path(@conn, :create)) %> <span><%= link "Back", to: enr_admission_path(@conn, :index) %></span>
scope "/", InsWeb do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
resources "/users", UserController
resources "/sessions", SessionController, only: [:new, :create, :delete],
singleton: true
resources "/admissions", AdmissionController, only: [:new, :create, :show]
end
scope "/ENR", InsWeb.ENR, as: :enr do
pipe_through [:browser, :authenticate_user]
resources "/admissions", AdmissionController
end
defp authenticate_user(conn, _) do
case get_session(conn, :user_id) do
nil ->
conn
|> Phoenix.Controller.put_flash(:error, "Login required")
|> Phoenix.Controller.redirect(to: "/")
|> halt()
user_id ->
assign(conn, :current_user, Ins.Accounts.get_user!(user_id))
end
end
一切似乎都很好,我達到了通過公開部分入學頁面,但是當我提交表單==== nothing..I總是在CMS了「需要登錄」 所以這是不可能的,讓學生自行註冊...
而另外三分之一的CMS
defmodule InsWeb.AdmissionController do
use InsWeb, :controller
alias Ins.ENR
alias Ins.ENR.Admission
def new(conn, _params) do
changeset = ENR.change_admission(%Admission{})
render(conn, "new.html", changeset: changeset)
end
def create(conn, %{"admission" => admission_params}) do
case ENR.create_admission(conn.assigns.current_enroller, admission_params) do
{:ok, admission} ->
conn
|> put_flash(:info, "Admission created successfully.")
|> redirect(to: enr_admission_path(conn, :show, admission))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
def show(conn, %{"id" => id}) do
admission =
id
|> ENR.get_admission!()
render(conn, "show.html", admission: admission)
end
end
任何幫助,將不勝感激!謝謝!
感謝您的回覆@guitarman,我構建了2個控制器,但它是相同的結果。我編輯了我的問題,向你展示'CMS'範圍內的'AdmissionController.ex'。 –
我正在使用** Phoenix 1.3 **。 –
我在我的Phoenix 1.3應用程序中嘗試了不同的命名。 'resources'/ admissions「,AdmissionController'中使用的控制器對於兩個範圍都是相同的。檢查'混合php.routes'。 請提供new.html.eex的HTML以及是否存在form.html.eex。 – guitarman