在阅读了Ruby on Rails安全指南和研究其他成功应用的方法之后,我找到了一种更好的生成访问令牌的方式。
在询问这个问题之前,我曾经尝试使用Facebook Graph API,并且我知道我想能够像这样发出RESTful请求:
GET /me?access_token=4976517fd7814040b2083864973ff422
通过 access_token
,服务器可以返回关于我
的信息。
因此,我认为 access_token
必须是唯一的,这样服务器才能执行类似以下操作:
SELECT * FROM users WHERE access_token = '4976517fd7814040b2083864973ff422'
让我们来看一些来自其他成功API的访问令牌示例。
Facebook: 50601675619|5Lfrygz7QmiNVSgkvryzixIVHuo
(应用令牌)
Twitter: 191074378-1GWuHmFyyKQUKWV6sR6EEzSCdLGnhqyZFBqLagHp
Instagram: fb2e77d.47a0479900504cb3ab4a1f626d174d2d
GitHub: e72e16c7e42f292c6912e7710c838347ae178b4a
Facebook和Twitter都明确地在用户的访问令牌前缀中加上了他的ID。Instagram似乎也是这样做的,只是编码了。这样的访问令牌本质上有两个部分:用户ID和会话ID。
嵌入用户ID的访问令牌使服务器能够:
SELECT * FROM users WHERE id = '50601675619'
然后,它可以简单地检查访问令牌的第二部分是否与存储在数据库中该用户的会话ID匹配,类似于验证登录期间的用户名和密码。
Instagram访问令牌的第二部分似乎是一个没有连字符的小写版本4 UUID。因此,我将按照@a_horse_with_no_name的评论和@ClodoaldoNeto的答案进行操作。除此之外,我将把列access_token
重命名为session_id
并移除UNIQUE
约束。
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
);
insert into user_table default values
returning access_token;
access_token
--------------------------------------
341ab75c-6b4e-4df0-a2ea-5148434fce5a
要使用uuid
函数,需要以超级用户身份在目标数据库中安装uuid-ossp
扩展。
create extension "uuid-ossp";
uuid
函数,或者从其他地方获取该函数。smallserial
?使用bigserial
,您将永远不会用完数字。从一开始就限制自己只有32767行是值得怀疑的。 - user330315
access_token
设置为随机字符串并返回该值。请参阅http://www.postgresql.org/docs/9.3/static/sql-createtrigger.html。 - user1509107