Vaadin login with Facebook - day28

目的

使用 Facebook 登入
https://ithelp.ithome.com.tw/upload/images/20211014/20138680a05XKGF0kW.png

https://ithelp.ithome.com.tw/upload/images/20211014/20138680cplAWrDYbA.png

本日重点 :

  • 本篇使用 Facebook Graph API 登入
  • Facebook 建立应用程序
  • Vaadin 接收网址参数
  • ngrok 让外网可连本机

仅列出关键步骤

准备工作

建立 Facebook 应用程序

请到 Facebook 开发者网站 建立应用程序,步骤如下:
https://ithelp.ithome.com.tw/upload/images/20211014/20138680jFQPl7E23d.png

https://ithelp.ithome.com.tw/upload/images/20211014/201386800D8PQJmBSP.png
选取商品
https://ithelp.ithome.com.tw/upload/images/20211014/20138680CnPR4rXWlS.png
有几个地方需特别注意,应用程序网域隐私政策网址用户资料删除 都是必填资料,可先随便填,应用程序网域ngrok执行後,可填写 ngrok提供的网域。
https://ithelp.ithome.com.tw/upload/images/20211014/201386801Sv2r2Lxr7.png
有效的 OAuth 重新导向 URI必须填写正确,facebook 登入後会导到此页面,此页面接收参数 code 用以後续作业。
https://ithelp.ithome.com.tw/upload/images/20211014/201386801gLmR982yc.png
使用Facebook登入须取得 public_profile 进阶存取权限。
https://ithelp.ithome.com.tw/upload/images/20211014/201386803nT4SCi0F7.png
https://ithelp.ithome.com.tw/upload/images/20211014/20138680nSDnNpO22O.png

安装 ngrok

ngrok 收费标准如下,用於本机使用免费版就可以了。
https://ithelp.ithome.com.tw/upload/images/20211014/20138680EkCm7cMJk0.png

由此下载安装

执行

ngrok http 8080

Facebook 只接受 https,待Vaadin程序开发完成、执行後,请复制 ngrok 提供的 https 网址,填入应用程序网域有效的 OAuth 重新导向 URI。当然,虽然尚未开发用户删除,也可先填入用户资料删除
https://ithelp.ithome.com.tw/upload/images/20211014/20138680AbcK4U0lWI.png

正文开始

登入按键

    button(" Login with Facebook"){
        icon = Icon(VaadinIcon.FACEBOOK).apply {
            color = "#4267b2"
            style.set("background-color", "#ffffff")
            style.set("border-radius", "5px")
        }

        width = "250px"
        height = "40px"
        style.set("background-color", "#4267b2")
        style.set("color", "#ffffff")
        style.set("border-radius", "5px")
        addClickListener {
            val fbConnection = FBConnection()
            UI.getCurrent().page.setLocation(fbConnection.fBAuthUrl)
        }
    }

按键样式多了点,这些之後都可以改放在style里,再套用就行了。FBConnection()取得Facebook登入网址。

取得 Facebook 服务网址/AccessToken

  • fBAuthUrl => facebook 登入网址
  • getFBGraphUrl => 取得AccessToken网址
class FBConnection {
    val fBAuthUrl: String by lazy {
        "http://www.facebook.com/dialog/oauth?client_id=$FB_APP_ID&redirect_uri=${
            URLEncoder.encode(
                REDIRECT_URI,
                "UTF-8"
            )
        }&scope=email"
    }

    fun getFBGraphUrl(code: String): String {
        val fbcode = code
        var fbGraphUrl = "https://graph.facebook.com/oauth/access_token?client_id=${FB_APP_ID}&redirect_uri=${
            URLEncoder.encode(
                REDIRECT_URI,
                "UTF-8"
            )
        }&client_secret=${FB_APP_SECRET}&code=${fbcode}"
        return fbGraphUrl
    }

    fun getAccessToken(code: String): String {
        if ("" == accessToken) {
            val data = URL(getFBGraphUrl(code)).readText()
            val obj = JSONObject(data)
            accessToken = obj.getString("access_token")
        }
        return accessToken
    }

    companion object {
        val FB_APP_ID = "<your FB_APP_ID>"
        val FB_APP_SECRET = "<your FB_APP_SECRET>"
        val REDIRECT_URI = "<your Callback page>"
        var accessToken = ""
    }
}

REDIRECT_URI须和Facebook应用程序有效的 OAuth 重新导向 URI网址一致。

Callback Page

使用VaadinRequest取得网址参数 code,fb 登入大致流程如下 :
本网按下FB登入 -> 呼叫fb登入页 -> 本网callback页 -> 使用fb登入带回的code查 access_token -> 拿access_token去查需要的资料。

Facebook Graph API 规格请看 说明文件

@AllowAll
@Route(value = "fb-callback", layout = MainLayout::class)
class FacebookLoginSuccessView : KComposite() {
    private var fbProfileData: Map<String, Any>?
    private lateinit var email: Paragraph
    private lateinit var name: H4
    var code:String

    init {
        code = VaadinRequest.getCurrent().getParameter("code")
        val fbConnection = FBConnection()
        val accessToken = fbConnection.getAccessToken(code)
        val fbGraph = FBGraph(accessToken)
        val graph = fbGraph.getGraph()
        fbProfileData =  fbGraph.getGraphData(graph)
    }

    private val root = ui {
        verticalLayout {
            h2("Facebook 登入")
            name = h4("观迎 ${fbProfileData?.get("name")}")
        }
    }
}

<<:  Day 28. Hi-Fi Prototype-以 Figma 制作高精度原型 (上)

>>:  [Day 28] PHP array_column / array_keys / array_values

Day 06:小孩子才做选择-BootstrapVue 全部引入

本篇开始终於要进入解决需求的前置作业了!首先需要让网站有个基本的置顶导览列,让我们有请 Bootst...

Best Web Hosting Affiliate Program

The platform provides a range of hosting options, ...

创建App-自创简略帐号设定

创建App-自创简略帐号设定 由於App的最後设定界面的延伸界面没有设计与排版,因此考虑到学生相关的...

仿Trello - 前端 Apollo Client 串接 GraphQL API

本系列文以制作专案为主轴,纪录小弟学习React以及GrahQL的过程。主要是记下重点步骤以及我觉...

Day29 Blazor 单元测试

开发一个系统最无聊的过程大概就是除错了,尤其是那种尝试对 null 物件取值的错误(Object r...