关于存储过程:PostgreSQL:在插入时创建访问令牌

PostgreSQL: Create Access Token on Insert

在插入时,如何将EDOCX1的值(0)唯一地设置为随机字符串并将该值返回给客户机?

我有:

1
2
3
4
5
CREATE TABLE USER (
    id             serial PRIMARY KEY,
    access_token   CHAR(32) NOT NULL UNIQUE,
    joined         TIMESTAMP WITH TIME zone NOT NULL DEFAULT CURRENT_TIMESTAMP
);

数据库服务器:PostgreSQL应用服务器:Sinatra(Ruby)客户端:iOS


在阅读了RubyonRails安全指南并研究了其他成功的应用程序是如何做到这一点之后,我找到了一种生成访问令牌的更好方法。

旧思维

在问这个问题之前,我已经使用了Facebook图形API,我知道我希望能够提出一个安静的请求,比如:

1
GET /me?access_token=4976517fd7814040b2083864973ff422

access_token服务器可以返回关于me的信息。

因此,我认为access_token必须是UNIQUE,这样服务器才能执行如下操作:

1
SELECT * FROM users WHERE access_token = '4976517fd7814040b2083864973ff422'

新思维

让我们看看其他成功的API中访问令牌的一些例子。

facebook:50601675619|5Lfrygz7QmiNVSgkvryzixIVHuo(app token)推特:191074378-1GWuHmFyyKQUKWV6sR6EEzSCdLGnhqyZFBqLagHp实例图:fb2e77d.47a0479900504cb3ab4a1f626d174d2d。Github:e72e16c7e42f292c6912e7710c838347ae178b4a

Facebook和Twitter都清楚地在用户的访问令牌前面加上了自己的ID。Instagram似乎也这样做,只是进行了编码。这样的访问令牌基本上有两部分:用户ID和会话ID。

嵌入用户ID的访问令牌允许服务器:

1
SELECT * FROM users WHERE id = '50601675619'

然后,它可以简单地检查访问令牌的第二部分是否与存储在该用户数据库中的会话ID匹配,类似于在登录期间验证用户名和密码。

最终解决方案

Instagram访问令牌的第二部分似乎是无连字符的较低版本4 UUID。因此,我将按照@a_horse_的评论和@clodoaldoneto的回答来做同样的事情。但是,我将把列access_token重命名为session_id并删除UNIQUE约束。


如上所述,使用uuid

1
2
3
4
5
CREATE TABLE user_table (
    id             serial PRIMARY KEY,
    access_token   uuid DEFAULT uuid_generate_v4() NOT NULL UNIQUE,
    joined         TIMESTAMP WITH TIME zone NOT NULL DEFAULT CURRENT_TIMESTAMP
);

然后插入默认值

1
2
3
4
5
INSERT INTO user_table DEFAULT VALUES
returning access_token;
             access_token            
--------------------------------------
 341ab75c-6b4e-4df0-a2ea-5148434fce5a

为了能够使用uuid功能,需要在目标数据库中安装uuid-ossp扩展作为超级用户。

1
CREATE extension"uuid-ossp";

您可以使用Ruby中的uuid函数,或者如果它们不存在于其他地方。

现在阅读您的评论,看起来您正在处理会话ID。

可以使用UUID生成器生成会话ID。但请注意,会话ID只是特定会话的ID。每次用户登录时,它都会更改。会话ID不应存储在用户表中。

通常,会话由应用程序使用框架提供的模块处理。该模块将有自己的方法来存储会话ID和会话数据。一般来说,会话ID放在cookie中,而不是URL中。应用程序将向会话管理器传递一个salt,它将负责生成会话ID并保持其状态,无论是在cookie中、在URL中、在页面中,无论是什么。模块将把会话数据存储在它配置的位置,内存、磁盘文件、数据库。

所以不要自己做会话管理。让它进入框架的解决方案。更简单,更重要,更安全。