iT邦幫忙

2021 iThome 鐵人賽

DAY 10
0
Modern Web

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

VoK 整合式登入 - day10

登入功能不外乎輸入帳密、驗證、賦予角色功能權限。Vaadin-on-Kotlin 提供了 VoK-Security API 用以達成上述功能,本文將使用VoK整合式登入畫面。

登入

  1. 開新檔案 LoginServlices.kt
package com.example.vok

import com.vaadin.flow.component.UI
import eu.vaadinonkotlin.vaadin10.Session
import java.io.Serializable

class LoginServices: Serializable {
    var currentUser: User? = null
        private set
    val isLoggedIn get() = currentUser != null

    fun login(username: String, password: String): Boolean{
        // TODO verify username and password
        currentUser = User(username)
        UI.getCurrent().page.reload()
        return true
    }

    fun logout(){
        Session.current.close()
        UI.getCurrent().navigate("")
        UI.getCurrent().page.reload()
    }
}

val Session.loginService: LoginServices
    get() = getOrPut { LoginServices() }

data class User(val name: String) : Serializable

currentUser 可供讀取,但不提供其他程式賦值。
本範例並未實際檢查使用者帳號密碼是否正確,當login()被呼叫直接設定該user為登入狀態,並更新畫面。
logout()被呼叫時,清除Session、導至首頁後更新畫面。

val Session.loginService: LoginServices
    get() = getOrPut { LoginServices() }

亦即當 Session.loginService 被讀取時,若已存在就直接取用,若不存在就新增一個 LoginSerivces()

  1. 登入畫面, 開啟新檔 LoginView.kt
package com.example.vok

import com.github.mvysny.karibudsl.v10.*
import com.vaadin.flow.component.login.LoginForm
import com.vaadin.flow.component.login.LoginI18n
import com.vaadin.flow.router.BeforeEnterEvent
import com.vaadin.flow.router.BeforeEnterObserver
import com.vaadin.flow.router.Route
import eu.vaadinonkotlin.vaadin10.Session

@Route("login")
class LoginView: KComposite(), BeforeEnterObserver {
    private lateinit var loginForm: LoginForm

    private val root = ui{
        verticalLayout {
            setSizeFull(); isPadding = false; content { center() }
            val loginI18n: LoginI18n = loginI18n {
                header.title = "您好!"
                additionalInformation = "請登入"
            }
            loginForm = loginForm(loginI18n){
                addLoginListener {event ->
                    isError = !Session.loginService.login(event.username, event.password)
                }
            }
        }
    }

    override fun beforeEnter(event: BeforeEnterEvent) {
        if (Session.loginService.isLoggedIn){
            event.rerouteTo("")
        }
    }

}

LoginForm 是 Vaadin 提供的 UI Component,LoginI18n 則是提供LoginForm需要的資料,使用編碼為 UTF8。

  1. 在開啟頁面前檢查登入狀態,請打開MainLayout.kt
@Viewport(Viewport.DEVICE_DIMENSIONS)
class MainLayout: KComposite(), RouterLayout, BeforeEnterObserver {
    private val root = ui {
        div {
            setSizeFull()
        }
    }
}

  override fun beforeEnter(event: BeforeEnterEvent) {
    if (event.navigationTarget != LoginView::class.java && !Session.loginService.isLoggedIn) {
      event.rerouteTo(LoginView::class.java)
    }
  }

@Viewport 即 html 的 <meta name=”viewport”> 為了符合不同尺寸裝置最佳瀏覽
MainLayout.kt 加上檢查,只要上層layout為 MainLayout,在進入該頁面前,皆會執行檢查登入狀態。

執行結果

https://ithelp.ithome.com.tw/upload/images/20210926/20138680BO2pTHaliL.png

自訂文字

登入提示文字可修改為中文或任意文字

            val loginI18n: LoginI18n = loginI18n {
                header.title = "您好!"
                with(form){
                    title = "登入"
                    username = "帳號"
                    password = "密碼"
                    submit = "登入"
                    forgotPassword = "忘記密碼"
                }
                additionalInformation = "請登入"

            }

改為中文後,執行結果如下
https://ithelp.ithome.com.tw/upload/images/20210926/20138680qFPCI44XxS.png

登入可以做得很複雜,也可以很簡單,VoK的整合登入畫面僅提供帳號密碼輸入。

本日程式已上傳 GitHub


上一篇
vok-orm 關聯性資料的新增/查詢 (下篇) + Vaadin 自訂樣式 - d09
下一篇
vok-orm 刪除關連資料 - day11
系列文
使用 Kotlin 快速開發 Web 程式 -- Vaadin30

尚未有邦友留言

立即登入留言