#elixir #phoenix-framework
#elixir #phoenix-фреймворк
Вопрос:
Я пишу пример приложения для Phoenix Framework. моя аутентификация.пример:
defmodule Myapp.Plug.Authenticate do
import Plug.Conn
import Myapp.Router.Helpers
import Phoenix.Controller
def init(default), do: default
def call(conn, default) do
current_user = get_session(conn, :current_user)
if current_user do
assign(conn, :current_user, current_user)
else
conn
|> put_flash(:error, 'You need to be signed in to view this page')
|> redirect(to: session_path(conn, :new))
end
end
end
существует контроллер, в котором мне не требуется аутентификация для одного действия:
defmodule Myapp.SharedLinkController do
use Myapp.Web, :controller
alias Myapp.SharedLink
plug Myapp.Plug.Authenticate when action in [:new, :create]
...
end
это работает, но проблема в том, что там отображение меню зависит от того, авторизован пользователь или нет:
<%= if Map.has_key?(@conn.assigns, :current_user) do %>
<li>first</li>
<% else %>
<li>second</li>
<% end %>
и получается, что на странице action, для которой я не требую аутентификации, я получаю, что пользователь не авторизован, даже когда он авторизован. как я могу решить эту проблему?
Комментарии:
1. «Я понимаю, что пользователь не авторизован» вы имеете в виду, что вы получаете flash и перенаправление или вы получаете неправильное меню?
2. @Dogbert, я получаю неправильное меню
3. Какое значение имеет
@conn.assigns[:current_user]
при выходе из системы? Попробуйте добавить<%= inspect @conn.assigns[:current_user] %>
и посмотрите результат.4. Работает ли это:
<%= if assigns[:current_user] do %>
?5. Вы должны вызвать halt/1 в функции вызова после перенаправления, чтобы предотвратить вызов дальнейших подключений ниже по потоку. Также в вашем шаблоне вы должны иметь возможность вызывать
<%= if @current_user do %>
, чтобы проверить, аутентифицирован ли пользователь или нет. ПРИВЕТ
Ответ №1:
Я бы разделил код на два этапа — сначала попытка аутентификации пользователя, загрузка из базы данных и назначение соединению — вы всегда можете запустить этот и просто назначить nil
специального гостевого пользователя или ничего, как вам больше нравится. Вторым будет принудительная проверка подлинности пользователя на основе назначений в соединении — этот будет запускаться только там, где вам нужно — как подключаемый модуль, который у вас есть в данный момент.
Комментарии:
1. Правильно ли я вас понимаю, я должен выполнить две «аутентификации» — «мягкий» вариант, целью которого является присвоение текущего пользователя или гостя, и второй вариант — «жесткий», который перенаправляет на страницу входа, если пользователь не авторизован?
2. Да, это идея.