这是一个非常简单的例子,演示了如何用Cassandra数据库管理用户账户。它可以帮助你采用一些公共和私人(认证)的功能。查看这个优秀的Cassandra数据建模视频教程和它的相关代码。
数据库
CREATE KEYSPACE IF NOT EXISTS blog
WITH REPLICATION = {
'class': 'NetworkTopologyStrategy',
'datacenter1': 1
};
DROP TABLE IF EXISTS blog.user_accounts;
CREATE TABLE IF NOT EXISTS blog.user_accounts (
id uuid,
name text,
email text,
created_at timestamp,
deleted_at timestamp,
PRIMARY KEY (id)
);
DROP TABLE IF EXISTS blog.user_credentials;
CREATE TABLE IF NOT EXISTS blog.user_credentials (
email text,
password text,
user_account_id uuid,
deleted_at timestamp,
PRIMARY KEY (email)
);
DROP TABLE IF EXISTS password_recovery_tokens;
CREATE TABLE IF NOT EXISTS password_reset_tokens (
"token" text,
email text,
user_account_id uuid,
PRIMARY KEY ("token")
) WITH default_time_to_live = 3600;
设计
为了实现一件事,不可避免地要运行多个查询。然而,由于设计的原因,带有条件的批处理操作不能跨越多个表,所以你必须确保手动回滚。
注册一个新用户(公开)
创建一个新的用户从user_credentials 开始,因为它执行email 的唯一性。之后,user_accounts ,使用同样的email 和id ,从user_credentials 开始创建。id 的唯一性由user_accounts 执行,所以在发生冲突的情况下,user_credentials 必须回滚。id 是一个用户的全局标识符,永远不会改变。这个值可以在其他表中用来表示用户关联:
// Creates `user_credentials` unless `email` value is taken.
INSERT INTO user_credentials (email, password, user_account_id)
VALUES (?, ?, ?) IF NOT EXISTS;
// Creates `user_accounts` unless `id` value is taken.
INSERT INTO user_accounts (id, name, created_at, email)
VALUES (?, ?, ?, ?) IF NOT EXISTS;
忘记密码(公开)
你所需要知道的是发送密码恢复链接的电子邮件地址。如何构建令牌值由你决定。它可能只是一个哈希值或编码的令牌。令牌默认在1小时内过期,如在表层用default_time_to_live 定义:
// Select current data.
SELECT * FROM user_credentials WHERE email = 'current email';
// Insert new password reset token record.
INSERT INTO password_reset_tokens (token, email, user_account_id)
VALUES (?, ?, ?) IF NOT EXISTS;
重置密码(公开)
你已经有了附加在链接上的令牌。如果你的令牌是一个包含用户数据的编码值,你可以对来自数据库的数据进行解码和验证:
// Select current token.
SELECT * FROM password_reset_tokens WHERE token = ?;
// Update password.
UPDATE user_credentials SET password = ? WHERE email = 'current email' IF EXISTS;
// Delete current token.
DELETE FROM password_reset_tokens WHERE token = ?;
登录用户(公开)
// Select user and verify password.
SELECT * FROM user_credentials WHERE email = ?;
更改电子邮件地址 (私人)
你已经登录了,所以电子邮件是已知的:
// Select current data.
SELECT * FROM user_credentials WHERE email = 'current email';
// Create a new record using new and current data.
INSERT INTO user_credentials (email, password, user_account_id)
VALUES ('new email', 'current password', current uuid) IF NOT EXISTS;
// Update current email with new one.
UPDATE user_accounts SET email = 'new email' WHERE id = current uuid IF EXISTS;
// Delete redundant record.
更改密码 (私人)
你已经登录了,所以电子邮件是已知的。这种操作通常需要预先确认密码:
// Update current password with new one.
UPDATE user_credentials SET password = ? WHERE email = ? IF EXISTS;
删除账户 (私密)
你已经登录了,所以你的电子邮件是已知的。这样的操作往往需要事先确认密码。硬删除通常不是一个选项。使用软删除,将记录标记为带有时间戳的 "已删除":
// Select current data.
SELECT * FROM user_credentials WHERE email = 'current email';
// Soft delete.
UPDATE user_credentials SET deleted_at = ? WHERE email = 'current email' IF EXISTS;
UPDATE user_accounts SET deleted_at = ? WHERE id = current uuid IF EXISTS;