Добавление кнопки для входа в Google с помощью F#/fable/asp.net/ реагировать

Я работаю со стеком SAFE ( https://safe-stack.github.io/) и через пример dojo. Пока все отлично.

Я хотел бы расширить пример, чтобы включить кнопку для входа / авторизации через Google. Поэтому я посмотрел пример на веб-сайте Google ( https://developers.google.com/identity/sign-in/web/build-button). А потом я посмотрел, как сделать аутентификацию с использованием ASP.NET ( https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/google-logins?view=aspnetcore-2.1&tabs=aspnetcore2x) В результате я запутался в том, как интегрировать это в БЕЗОПАСНЫЙ проект. Может кто-нибудь сказать мне, что они будут делать? Должен ли я пытаться использовать ASP.NET Identity или я должен использовать подход JWT? Я даже не знаю, одинаковы ли они, так как я очень плохо знаком с веб-фреймворками.....

Другой вопрос, который у меня есть, заключается в том, как внедрить необработанный Javascript в клиентскую часть проекта SAFE. Пример Google выше показывает необработанный код JS/CSS/HTML? Должен ли я вводить это как есть или я должен искать в React какую-то кнопку, которая делает это и отображает эту идею обратно через Fable?

1 ответ

Решение

Настройка OAuth

Самый простой способ использовать Google OAuth - подождать до следующей версии Сатурна, после чего Сатурн будет включать use_google_oauth особенность, которую я только что добавил.:-) Посмотрите исходный код, если вам интересно, как он работает, хотя, боюсь, вы не сможете реализовать это самостоятельно с use_custom_oauth потому что вы столкнетесь с ошибкой типа (основной код ASP.NET имеет класс GoogleOptions, и use_custom_oauth хочет класс OAuthOptions, и они не совместимы).

Чтобы использовать его, добавьте следующее к вашему application CE:

use_google_oauth googleClientId googleClientSecret "/oauth_callback_google" []

Последний параметр должен быть последовательностью string * string пары, которые представляют ключи и значения: вы можете использовать список кортежей или карту, переданную через Map.toSeqили что угодно. Ключи этой последовательности - это ключи в структуре JSON, которые Google возвращает для вызова API "получить более подробную информацию об этом человеке", а значения - это типы утверждений, которым эти ключи должны быть сопоставлены в системе утверждений ASP.NET. Отображение по умолчанию, которое use_google_oauth уже делает это:

  • id → ClaimTypes.NameIdentifier
  • displayName → ClaimTypes.Name
  • emails[] (см. примечание) → ClaimTypes.Email

Эти три автоматически отображаются в ASP.NET. Я добавил четвертое отображение:

  • avatar.url → `" urn: google: avatar: url "

Для этого имени нет стандартного имени ClaimTypes, поэтому я выбрал произвольный URN. Предостережение: эта функция еще не была выпущена, и вполне возможно (хотя и маловероятно), что эта строка может измениться между настоящим моментом и выпуском этой функции в следующей версии Saturn.

С этими четырьмя типами утверждений, сопоставленными автоматически, я обнаружил, что мне не нужно указывать никаких дополнительных утверждений, поэтому я оставил последний параметр для use_google_oauth как пустой список в моем демонстрационном приложении. Но если вы хотите больше (скажем, хотите, чтобы предпочитаемый язык пользователя использовался в вашей локализации), просто добавьте их в этот список, например:

use_google_oauth googleClientId googleClientSecret "/oauth_callback_google" ["language", "urn:google:language"]

А потом, когда кто-то вошел в систему, посмотрите в User.Claims Seq для претензии типа "urn:google:language",

Примечание re: emails[] Список в JSON: я не проверял это с учетной записью Google, которая имеет несколько электронных писем, поэтому я не знаю, как ASP.NET выбирает электронное письмо для включения в претензию ClaimTypes.Email. Он может просто выбрать первое электронное письмо в списке, или он может выбрать один с type из account; Я просто не знаю. Некоторые эксперименты могут быть необходимы.

Также обратите внимание, что сторонний OAuth, включая GitHub и Google, был разделен на новый пакет Saturn.Extensions.Authorization. Он будет выпущен на NuGet одновременно с выходом следующей версии Saturn (вероятно, 0.7.0).

Создание кнопки

Когда у вас есть use_google_oauth позвоните в ваш applicationсоздайте что-то вроде следующего:

let googleUserIdForRmunn = "106310971773596475579"
let matchUpUsers : HttpHandler = fun next ctx ->
    // A real implementation would match up user identities with something stored in a database, not hardcoded in Users.fs like this example
    let isRmunn =
        ctx.User.Claims |> Seq.exists (fun claim ->
            claim.Issuer = "Google" && claim.Type = ClaimTypes.NameIdentifier && claim.Value = googleUserIdForRmunn)
    if isRmunn then
        printfn "User rmunn is an admin of this demo app, adding admin role to user claims"
        ctx.User.AddIdentity(new ClaimsIdentity([Claim(ClaimTypes.Role, "Admin", ClaimValueTypes.String, "MyApplication")]))
    next ctx

let loggedIn = pipeline {
    requires_authentication (Giraffe.Auth.challenge "Google")
    plug matchUpUsers
}

let isAdmin = pipeline {
    plug loggedIn
    requires_role "Admin" (RequestErrors.forbidden (text "Must be admin"))
}

И теперь в вашей области видимости (ПРИМЕЧАНИЕ: "видимость", вероятно, будет переименована в "маршрутизатор" в Saturn 0.7.0), сделайте что-то вроде этого:

let loggedInView = scope {
    pipe_through loggedIn

    get "/" (htmlView Index.layout)
    get "/index.html" (redirectTo false "/")
    get "/default.html" (redirectTo false "/")
    get "/admin" (isAdmin >=> htmlView AdminPage.layout)
}

И наконец, пусть ваш главный маршрутизатор имеет URL, который передает данные loggedInView маршрутизатор:

let browserRouter = scope {
    not_found_handler (htmlView NotFound.layout) //Use the default 404 webpage
    pipe_through browser //Use the default browser pipeline

    forward "" defaultView //Use the default view
    forward "/members-only" loggedInView
}

Тогда ваша кнопка входа в систему может просто перейти к /members-only маршрут, и вы будете в порядке.

Обратите внимание, что если вы хотите использовать несколько кнопок OAuth (Google, GitHub, Facebook и т. Д.), Вам, вероятно, придется немного их настроить, но этот ответ уже достаточно длинный. Когда вы дойдете до того, что захотите использовать несколько кнопок OAuth, задайте другой вопрос.

Другие вопросы по тегам