Как реализовать аутентификацию Google в блестящем R-приложении? - PullRequest
0 голосов
/ 15 мая 2018

Я хотел обеспечить базовую аутентификацию для своего блестящего приложения, и в идеале я не хотел иметь дело с протоколом входа или управлением паролем. Я хотел, чтобы мое приложение предоставляло общедоступное представление данных, но если пользователь прошел аутентификацию, тогда будут доступны персонализированные наборы данных. В лучшем случае я хотел использовать федеративный логин, например Google.

Одним из решений является использование прокси ( auth0 , sparkProxy ). Это тяжелое решение, требующее запуска дополнительных сервисов. Кроме того, не существует простого способа связать имя пользователя с блестящим сервером, что было моей главной целью. И прокси не позволяет приложению работать в режиме без аутентификации, который мне требуется.

Другим решением является создание относительно простого интерфейса имени пользователя / пароля с использованием javascript. Вот пример . Но я бы предпочел не управлять аутентификацией по имени пользователя и паролю вручную. В моем приложении я хочу разрешить любому пользователю использовать приложение, но мне просто нужен уникальный идентификатор для каждого пользователя для персонализированного взаимодействия.

Так что, если я хочу использовать аутентификацию Google, то третий подход - использовать GoogleAuthR . Но я обнаружил, что библиотека была проблематичной, потому что я не мог заставить ее поддерживать постоянный вход в систему. Как и другие приложения, использующие федеративную регистрацию, я хотел, чтобы пользователь позже вернулся к URL и все еще был подключен.

1 Ответ

0 голосов
/ 15 мая 2018

Мое решение состояло в том, чтобы использовать Google Sign-In API , написать очень небольшое количество javascript и использовать функцию js Shiny.onInputChange для создания реактивных переменных из пользовательских данных.

API входа в систему предоставляет кнопку, не требует секрета и позволяет указывать идентификатор клиента и область действия в метатегах в HTML-заголовке, поэтому его очень легко использовать.

In app.R Я просто добавляю код Google API, область действия, идентификатор клиента и кнопку входа в систему, как это.

ui <- tagList(
  tags$head(
    tags$meta(name="google-signin-scope",content="profile email"),
    tags$meta(name="google-signin-client_id", content="YOURCLIENTID.apps.googleusercontent.com"),
    HTML('<script src="https://apis.google.com/js/platform.js?onload=init"></script>'),
    includeScript("signin.js"),
  ),
  fluidPage(

    titlePanel("Sample Google Sign-In"),

    sidebarLayout(
      sidebarPanel(
        div(id="signin", class="g-signin2", "data-onsuccess"="onSignIn"),
        actionButton("signout", "Sign Out", onclick="signOut();", class="btn-danger")

Обратите внимание, что API Google превратит div signin в кнопку, а параметр data-onsuccess называет функцию onSignIn для вызова при успешной аутентификации.Удобно, что это называется независимо от того, вошел ли пользователь в систему автоматически или проходит процесс одобрения Google.

Существует также функция signOut, которая делает недействительными локальные куки-файлы, а также аннулирует данные профиля.

В отдельном файле signin.js я определил функцию обратного вызова onSignIn, которая отправляет информацию профиля пользователяна блестящий сервер с клиента.

function onSignIn(googleUser) {
  var profile = googleUser.getBasicProfile();
  Shiny.onInputChange("g.id", profile.getId());
  Shiny.onInputChange("g.name", profile.getName());
  Shiny.onInputChange("g.image", profile.getImageUrl());
  Shiny.onInputChange("g.email", profile.getEmail());
}
function signOut() {
  var auth2 = gapi.auth2.getAuthInstance();
  auth2.signOut();
  Shiny.onInputChange("g.id", null);
  Shiny.onInputChange("g.name", null);
  Shiny.onInputChange("g.image", null);
  Shiny.onInputChange("g.email", null);
}

Вот и все.Ваш пользовательский интерфейс и сервер просто необходимо добавить код для доступа к профилям пользователей.Вот пример в пользовательском интерфейсе:

 mainPanel(
        with(tags, dl(dt("Name"), dd(textOutput("g.name")),
                      dt("Email"), dd(textOutput("g.email")),
                      dt("Image"), dd(uiOutput("g.image")) ))
      )

И на сервере:

server <- function(input, output) {
  output$g.name = renderText({ input$g.name })
  output$g.email = renderText({ input$g.email })
  output$g.image = renderUI({ img(src=input$g.image) })

Я собрал рабочий пример , который вы можете запустить (с оченьнебольшое искажение - вы должны указать порт 7445 и использовать localhost).Пожалуйста, прочитайте README для более подробной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...