登入功能不外乎輸入帳密、驗證、賦予角色功能權限。Vaadin-on-Kotlin 提供了 VoK-Security API 用以達成上述功能,本文將使用VoK整合式登入畫面。
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()
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。
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,在進入該頁面前,皆會執行檢查登入狀態。
登入提示文字可修改為中文或任意文字
val loginI18n: LoginI18n = loginI18n {
header.title = "您好!"
with(form){
title = "登入"
username = "帳號"
password = "密碼"
submit = "登入"
forgotPassword = "忘記密碼"
}
additionalInformation = "請登入"
}
改為中文後,執行結果如下
登入可以做得很複雜,也可以很簡單,VoK的整合登入畫面僅提供帳號密碼輸入。
本日程式已上傳 GitHub