代码之家  ›  专栏  ›  技术社区  ›  sashang

使用f/fable/asp.net/react为google登录添加按钮

  •  3
  • sashang  · 技术社区  · 7 年前

    我在用保险柜( https://safe-stack.github.io/ )并通过例子道场。到目前为止还不错。

    我想把这个例子扩展到包括一个通过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标识还是应该使用jwt方法?我甚至不知道它们是否相同,因为我对web框架非常陌生……

    另一个问题是如何将原始javascript注入安全项目的客户端。上面的google示例显示了原始js/css/html代码?我应该按原样注射,还是应该在react中寻找一个按钮来实现这个功能,并将这个想法映射回寓言中?

    1 回复  |  直到 7 年前
        1
  •  5
  •   rmunn    7 年前

    建立OAuth

    使用google oauth最简单的方法是等到下一个saturn版本发布,此时saturn将包含 use_google_oauth 我刚刚添加的功能。:-)见 the source code 如果你对它的工作方式感兴趣,尽管我担心你不能用 use_custom_oauth 因为您将遇到类型错误(底层的asp.net代码有一个googleoptions类,并且 使用自定义 想要一个oauthoptions类,但它们不兼容)。

    要使用它,请在 application 总工程师:

    use_google_oauth googleClientId googleClientSecret "/oauth_callback_google" []
    

    最后一个参数应该是 string * string 表示键和值的对:可以使用元组列表或传递的映射 Map.toSeq ,或其他。这个序列的键是 JSON structure that Google returns 对于“获取有关此人的详细信息”API调用,这些值是那些键应该在ASP.NET的声明系统中映射到的声明类型。默认映射 使用谷歌 已经做的是:

    • id ClaimTypes.nameIdentifier
    • displayName –`索赔类型.名称
    • emails[] (见注释)索赔类型。电子邮件

    这三个是由asp.net自动映射的。我添加了第四个映射:

    • avatar.url `“urn:google:avatar:url”

    这个没有标准的claimtypes名称,所以我选择了一个任意的urn。注意:这个功能还没有发布,而且这个字符串可能(虽然不太可能)在现在到下一个版本的土星中发布时发生变化。

    通过自动映射这四个声明类型,我发现不需要指定任何额外的声明,所以我将最后一个参数留给 使用谷歌 作为演示应用程序中的空列表。但是如果你想要更多(比如说你想让用户的首选语言在你的本地化中使用),那么只需将它们添加到列表中,例如:

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

    然后一旦有人登录,查看 User.Claims 类型索赔的顺序 "urn:google:language" 是的。

    注Re: 电子邮件[] json中的列表:我还没有用一个有多封电子邮件的google帐户测试过这个,所以我不知道asp.net如何选择一封电子邮件放入claimtypes.email声明中。它可能只选择列表中的第一封电子邮件,也可能选择带有 type 属于 account 我只是不知道。可能需要一些实验。

    还要注意的是,包括github和google在内的第三方oauth已经被拆分为一个新的saturn.extensions.authorization包。它将在土星下一个版本(可能是0.7.0)发布的同时在nuget上发布。

    制作按钮

    一旦你有了 使用谷歌 打电话给你 应用 ,创建如下内容:

    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按钮时,请继续问另一个问题。