Я пытаюсь настроить аутентификацию для приложения Shiny, которое использует JWT, и испытываю трудности с разбором возвращенного токена в server.R
.
В общем, пользователь пытается войти в систему, обработчик customHandler обращается к серверу аутентификации, и он возвращает JWT, если пользователь аутентифицирован. Затем JWT передается через AJAX-запрос к server.R
для разбора и сохранения в виде cookie.
Я определил session$registerDataObj()
как лучший кандидат для настройки, так как он создает конечную точку в server.R
для POST-запроса с JWT. Я могу успешно войти в систему и получить возвращенный JWT, но моя проблема заключается в извлечении этого JWT в server.R
для хранения и будущего использования. Для справки, я следую порядку здесь.
Вот основная функциональность в ui.R
, которая успешно извлекает JWT и отправляет его в server.R
:
...
const idToken = await user.getIdToken();
const sessionId = Shiny.shinyapp.config.sessionId;
const endpoint = `/session/${sessionId}/dataobj/process_token`;
fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ token: idToken })
}).then(response => {
if (response.ok) {
console.log('JWT успешно отправлен');
} else {
console.error('Не удалось отправить JWT на сервер Shiny');
}
});
} catch (error) {
console.error('Ошибка во время входа:', error.message);
}
})
...
…и пример реализации server.R
:
...
session$registerDataObj("process_token", data, function(data, req) {
if(req$REQUEST_METHOD == 'POST') {
# разбор данных / токена здесь + обработка ошибок
}
})
...
Я понимаю, что registerDataObj()
требует три предоставленные аргумента, но не знаю, как разобрать/извлечь токен из POST-запроса. Буду признателен за любую помощь!
Ответ
Ваша задача заключается в передаче и разборе JWT (JSON Web Token) в приложении Shiny с использованием функции session$registerDataObj()
. Давайте рассмотрим, как правильно обработать POST-запрос и извлечь токен из него.
Вы уже имеете часть реализации в файле ui.R
, которая правильно отправляет токен на сервер. Теперь давайте сосредоточимся на файле server.R
, где нужно будет зарегистрировать обработчик и разобрать полученные данные.
Вот пример кода, который поможет вам извлечь токен из POST-запроса и сохранить его (например, в куках):
library(shiny)
# Основная функция сервера
server <- function(input, output, session) {
session$registerDataObj("process_token", function(data, req) {
if (req$REQUEST_METHOD == 'POST') {
# Чтение тела запроса
body <- req$postBody
# Преобразование JSON в R-объект
json_data <- jsonlite::fromJSON(body)
# Извлечение токена
token <- json_data$token
# Теперь вы можете использовать токен по своему усмотрению
# Например, сохранение его в куки
session$sendCustomMessage(type = 'setCookie', list(cookieName = 'jwt', cookieValue = token))
# Вывод сообщения для отладки
cat("JWT получен и сохранён: ", token, "\n")
# Возврат ответа от сервера
return(list(status = "success", message = "Token processed successfully"))
} else {
return(list(status = "error", message = "Request method not supported"))
}
}, function(data, req) {
# Функция для обработки дополнительных параметров (если требуется)
return(NULL)
})
}
# UI компоненты
ui <- fluidPage(
# Ваш UI код здесь
)
# Запуск приложения
shinyApp(ui, server)
Пояснение к коду:
-
registerDataObj: Создаём новый объект данных, что позволяет обрабатывать POST-запросы.
-
req$postBody: Читаем тело запроса. В нашем случае это JSON-строка, содержащая JWT.
-
jsonlite::fromJSON(): Используем функцию из пакета
jsonlite
для конвертации JSON-строки в R-объект. -
Извлечение токена: Получаем токен из разобранного JSON и, например, сохраняем его в куки.
- Ответ: Возвращаем ответ клиенту с информацией о статусе обработки.
Настройка клиентской стороны:
Убедитесь, что ваша UI-часть настроена для корректного получения куки. Например, вы можете использовать дополнительные библиотеки (такие как js.cookie) для работы с куками на клиенте.
Заключение:
Теперь у вас есть полная реализация, которая позволяет полученному токену быть обработанным и сохранённым в куках при его получении через AJAX-запрос. Если у вас есть дополнительные вопросы, не стесняйтесь спрашивать!