Авторизация в ShinyDashboard (бесплатно и без СМС)

Опубликовано Опубликовано в рубрике Основная, Рецепты

Если вы долго и успешно внедряли в своей компании R, создавали дашборды Shiny и при этом основным вашим козырем было что это бесплатно, в отличии от Tableau, QlikView и прочих BI — рано или поздно вы натолкнетесь на грабли.
Давайте посмотрим такую ситуацию — вы крутите дашборд не на своей машине — вам удалось настроить Shiny Server, тот, который OpenSource — то есть бесплатный.
Так вот, грабли о которых я рассказывал заключаются в том, что не всем нужно и можно показывать те великолепные отчеты/дашборды — которые вы создали.
Встал вопрос об авторизации пользователей. И тут выясняется, что авторизация пользователей работает только в Shiny Server Pro (а он уже платный, причем по самой современной для индустрии, но самой неприятной для компании-пользователя схеме подписки).
И что, теперь снова идти к руководству и рассказывать, что вы заблуждались — и весь этот R на самом деле в итоге окажется для компании не такой уж бесплатный?

Ну уж нет. По секрету скажу, что решений есть несколько. Одним из вариантов, что встретился мне было использование дополнительного сервера Nginx как прокси к Shiny серверу. Решение концептуально понятное, но не очень радует. Грубо говоря — снова идти на поклон к админам Unix в компании и упрашивать их еще поставить дополнительное ПО на сервер. А вот окажутся они фанатами Apache — вообще замучаешься доказывать, что ты не баран.

Поэтому предлагаю вам решение проблемы авторизации в Shiny (в приложении к ShinyDashboard — это важно!).

Итак, основная идея такая: мы не изначально задаем ui компонент, а конкретно dashboardbody(), а сохраняем его в переменную через div().
То есть у нас обычно выглядит код так:
dashboardBody(tabItems(tabItem("Tab1"...))

Мы же поступим вот так:
mainbody <- div(tabItems(tabItem("Tab1"...))

Тогда сам dashboardBody() мы сможем определить вот так:
dashboardBody(uiOutput("body1"))

Это нам дает возможность в server() определить нашу форму:
output$body1 <- renderUI({mainbody})

А теперь ВНИМАНИЕ. Мы же можем ничего не меняя в сервере написать и вот так:
output$body1 <- renderUI({loginbody})
И тогда у нас на пользователя вывалится не тонна секретной информации - а форма, которая крайне вежливо и с прищуром спросит у него про пароль...

А так как мы это все делаем в server() где нам доступна вся логика - мы можем от результатов ввода в форме логина придумать что показать пользователю - то есть реализовали авторизацию.
Нам надо две формы (body) - для логина и основную. Для формы логина - пишем обработчик нажатия кнопки "Войти".
Внутри server() создаем "объект" пользователь:
user <- reactiveValues(Logged = FALSE, usrName='')

Правило проверки пароля для начала определим самое примитивное - "логин==пароль"

Кроме этого, в примере реализована также кнопка выход. И кнопка посмотреть под каким пользователем мы залогинены. Потому что если объект пользователь поместить чуть не в том месте - он будет одним и тем же для всех пользователей приложения :)

Также пришлось помучаться именно в концепции ShinyDashboard - хотелось получить чистое поле с окном логина - а не так уж просто из server() отключить header и sidebar.

Работающий пример выложен на Github.

PS. Кто узнает логотип, который использовался на форме входа - тот молодец :) !

Авторизация в ShinyDashboard (бесплатно и без СМС): 2 комментария

Добавить комментарий