PostgreSQL:在插入时创建访问令牌

ma1*_*w28 1 postgresql stored-procedures access-token

在插入,我应该怎么唯一设置的值access_token,以一个随机字符串和值返回给客户端?

我有:

CREATE TABLE user (
    id             serial PRIMARY KEY,
    access_token   char(32) NOT NULL UNIQUE,
    joined         timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP
);
Run Code Online (Sandbox Code Playgroud)

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

ma1*_*w28 6

阅读Ruby on Rails安全指南研究其他成功的应用程序如何做到这一点后,我想出了一种更好的方法来生成访问令牌.

旧思维

在提出这个问题之前,玩过Facebook Graph API,我知道我希望能够发出一个RESTful请求:

GET /me?access_token=4976517fd7814040b2083864973ff422
Run Code Online (Sandbox Code Playgroud)

从中access_token,服务器将能够返回有关的信息me.

因此,我认为access_token必须UNIQUE这样服务器可以做类似的事情:

SELECT * FROM users WHERE access_token = '4976517fd7814040b2083864973ff422'
Run Code Online (Sandbox Code Playgroud)

新思维

让我们看一些来自其他成功API的访问令牌的例子.

Facebook :( 50601675619|5Lfrygz7QmiNVSgkvryzixIVHuoApp Token)
Twitter:191074378-1GWuHmFyyKQUKWV6sR6EEzSCdLGnhqyZFBqLagHp
Instagram:fb2e77d.47a0479900504cb3ab4a1f626d174d2d
GitHub:e72e16c7e42f292c6912e7710c838347ae178b4a

Facebook和Twitter都清楚地在用户的访问令牌前面加上他的ID.Instagram似乎做了同样的事情,只是编码.这种访问令牌基本上有两部分:用户ID和会话ID.

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

SELECT * FROM users WHERE id = '50601675619'
Run Code Online (Sandbox Code Playgroud)

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

最终解决方案

Instagram的访问令牌的第二部分似乎是一个没有连字符的小写版本4 UUID.所以,我将跟随做同样的@a_horse_with_no_name评论答复@ClodoaldoNeto.除此之外,我会重命名列access_tokensession_id并删除UNIQUE约束.


Clo*_*eto 5

如上所述,使用uuid类型

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
);
Run Code Online (Sandbox Code Playgroud)

然后插入默认值

insert into user_table default values
returning access_token;
             access_token             
--------------------------------------
 341ab75c-6b4e-4df0-a2ea-5148434fce5a
Run Code Online (Sandbox Code Playgroud)

为了能够使用这些uuid功能,必须以uuid-ossp超级用户身份将扩展安装在目标数据库中

create extension "uuid-ossp";
Run Code Online (Sandbox Code Playgroud)

您可以使用uuid来自Ruby 的功能,也可以使用其他地方不存在的功能。


现在,阅读您的评论似乎就在会话ID之后。

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

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

因此,不要自己进行会话管理。让它成为框架的解决方案。更简单,非常重要,更安全。