使用 Facebook 登入

本日重點 :
僅列出關鍵步驟
請到 Facebook 開發者網站 建立應用程式,步驟如下:

選取商品
有幾個地方需特別注意,應用程式網域、隱私政策網址、用戶資料刪除 都是必填資料,可先隨便填,應用程式網域待ngrok執行後,可填寫 ngrok提供的網域。
有效的 OAuth 重新導向 URI必須填寫正確,facebook 登入後會導到此頁面,此頁面接收參數 code 用以後續作業。
使用Facebook登入須取得 public_profile 進階存取權限。

由此下載安裝
ngrok http 8080
Facebook 只接受 https,待Vaadin程式開發完成、執行後,請複製 ngrok 提供的 https 網址,填入應用程式網域、有效的 OAuth 重新導向 URI。當然,雖然尚未開發用戶刪除,也可先填入用戶資料刪除。
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登入網址。
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網址一致。
使用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")}")
}
}
}