iT邦幫忙

2021 iThome 鐵人賽

DAY 28
0
Modern Web

使用 Kotlin 快速開發 Web 程式 -- Vaadin系列 第 28

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")}")
        }
    }
}

上一篇
使用 Vaadin Directory 組件 - day27
下一篇
Vaadin Pro Components - CRUD - day29
系列文
使用 Kotlin 快速開發 Web 程式 -- Vaadin30

尚未有邦友留言

立即登入留言