VoK 系统功能权责划分 ( I ) - day13

权责划分

VoK整合登入

当使用者登入系统後,无论是因为使用者权责亦或是为了系统安全,通常会建立适当的安全机制,除了密码加密外,还有角色与权责分配,比如什麽样的角色(role)分配什麽样的功能。本节将带大家透过 VoK-Security 建立系统权责划分。

为系统建立适合的角色

在本范例学生成绩管理系统里,功能/角色分配如下 :

  • 角色 : administrator, teacher, student
  • 新增/修改/删除学生 - administrator
  • 查询学生 : 全部
  • 新增/修改/删除成绩 - teacher
  • 查询成绩 - 一般而言,学生仅能查到自己的成绩,但在本例中,学生为自动颜生,故分配只要具有 teacher, student 角色皆能查询成绩。

请打开 LoginServices.kt

修改 User()

data class User(
    override var id: Long? = null,
    var username: String = "",
    override var hashedPassword: String = "",
    var roles: String = ""
) : KEntity<Long>, HasPassword {
    companion object : Dao<User, Long>(User::class.java) {
        fun findByUsername(username: String): User? = findOneBy("username = :username") { query ->
            query.bind("username", username)
        }
    }
}

VoK Secruity 提供hash加密password,无需自行转换,只要实作 HasPassword,并复写 hashedPasswordHasPassword 将会於设定密码时,自动将加密後的 password 回写 hashedPassword

建立使用者资料表

在 web/src/main/resources/db/migration 下开新档案 V03__CreateUser.sql

create table user (
  id bigint auto_increment primary key not null,
  username varchar(100) not null,
  hashedPassword varchar(200) not null,
  roles varchar(400) not null
);
create unique index on user(username);

除了primary key外,username 为唯一值,且将会根据username查询,所以建立唯一值索引 (unique index)

检查登入帐密

修改login()

    fun login(username: String, password: String): Boolean {
        //verify username and password
        val user = User.findByUsername(username) ?: return false
        if (!user.passwordMatches(password)) return false
        currentUser = user
        UI.getCurrent().page.reload()
        return true
    }

第三行,倘若无此使用者,回传登入失败 (false)
第四行,使用 HasPassword 提供的方法 passwordMatches() 检查密码

增加必要方法

    fun getCurrentUserRoles(): Set<String>{
        val roles: String = currentUser?.roles ?: return setOf()
        return roles.split(",").toSet()
    }

    fun isUserInRole(role: String): Boolean = getCurrentUserRoles().contains(role)

    fun isAdmin(): Boolean = isUserInRole("administrator")

第三行,一个使用者可具多重角色,各角色间以,分隔
第六行,检查role是否存在

建立测试使用者资料

    User(username = "admin", roles = "admin").apply { setPassword("admin") }.save(false)
    User(username = "teacher", roles = "teacher").apply { setPassword("teacher") }.save(false)
    User(username = "student", roles = "student").apply { setPassword("student") }.save(false)

  • 使用 HasPassword 所提供的方法 setPassword() 设定密码
  • .save(false) 表示储存时不需检查资料正确性。

<<:  【Day28】this - call, apply, bind 与严谨模式

>>:  Day27 魔鬼中的天使

使用 JavaScript API 开发 Neo4j 应用程序

昨天分享过了 Neo4j HTTP API 的使用,所以如果你知道怎麽使用 JavaScript 呼...

【Day7】人算不如天算的运算式

这个部分算是JavaScript比较难缠的部分,不是难以理解,而是因为比较冗杂,稍稍心浮气躁,就没...

Dungeon Mizarka 008

战斗实际制作Part02 承接昨天的攻击功能制作。拿取到定位点後要转换成Raycast再进行侦测。为...

离职倒数28天:日本人办婚礼不登记的理由

跟老同事们说离职时,我很意外很多人第一个问题居然是问我是不是要结婚了。第一个人问时还有点反应不过来,...

[Day 25] - 『转职工作的Lessons learned』 - Cube.js(I)

今天要介绍一下工作上有使用的到的另一项工具 - Cube.js。 Cube.js 是一个开源的API...