如何通过自定义用户表进行认证
默认情况下,所有的用户信息都存储在 admin.sqlite 数据库中的一个表中。该表的结构是固定的,无法更改。
本节介绍如何使用自定义用户表中的数据进行用户认证。
首先,创建一个分组 认证(Authentication) ,选中它并添加一个名为 用户(Users) 的实体项,包含如下字段:
我们不会在表中直接存储用户密码,而是在界面中使用该字段。实际存储的是加盐后的密码哈希值,保存在 password_hash 字段中。
我们还创建了名为 “角色(Roles)” 的 查找列表 ,并在 “角色 “(Roles)” 字段定义中使用。
我们为其添加了与 角色 表中相同的角色(id 和名称)。后续需要保持这些角色的同步。
在 角色 中,需要设置只有负责该项的用户才能查看 用户(Users) 实体项。
我们在 查看表单对话框 和 编辑表单对话框 的字段列表中移除了 password_hash 字段。
在 用户(Users) 服务端模块中,定义如下 on_apply 事件处理程序:
def on_apply(item, delta, params, connection):
for d in delta:
if not (d.rec_deleted() or d.rec_modified() and d.login.value == d.login.old_value):
users = d.task.users.copy(handlers=False)
users.set_where(login=d.login.value)
users.open(fields=['login'])
if users.rec_count:
raise Exception('There is a user with this login - %s' % d.login.value)
if d.password.value:
d.edit();
d.password_hash.value = delta.task.generate_password_hash(d.password.value)
d.password.value = None
d.post();
在该事件处理程序中,我们检查是否有相同登录名的用户,如果有则抛出异常,否则用 task 的 generate_password_hash 方法生成哈希,并将密码字段设为 None。
在客户端模块中,定义如下 on_field_get_text 事件处理程序。它会将密码显示为 “******” :
function on_field_get_text(field) {
var item = field.owner;
if (field.field_name === 'password') {
if (item.id.value || field.value) {
return '**********';
}
}
}
最后,在 任务(Task) 的服务端模块中定义 on_login 事件处理程序:
def on_login(task, form_data, info):
users = task.users.copy(handlers=False)
users.set_where(login=form_data['login'])
users.open()
if users.rec_count == 1:
if task.check_password_hash(users.password_hash.value, form_data['password']):
return {
'user_id': users.id.value,
'user_name': users.name.value,
'role_id': users.role.value,
'role_name': users.role.display_text
}
现在需要在 用户(Users) 中添加一个有权限管理用户的管理员。之后即可在项目 参数 中启用安全模式(Safe mode)。