Session 处理OAuth响应&;会议
在OAuth2令牌交换结束时,我[通常]只剩下一个JSON用户数据数组,我已将其解编组到一个结构(比如GoogleUser)中,其中包含我关心的字段 将数据记录到数据库中的合理方式是什么?只需从回调处理程序调用Session 处理OAuth响应&;会议,session,cookies,oauth,go,Session,Cookies,Oauth,Go,在OAuth2令牌交换结束时,我[通常]只剩下一个JSON用户数据数组,我已将其解编组到一个结构(比如GoogleUser)中,其中包含我关心的字段 将数据记录到数据库中的合理方式是什么?只需从回调处理程序调用CreateUser函数,在检查用户在数据库中不存在后,传递结构并保存它(对我来说这是显而易见的方式) 我假设我应该在回调处理程序中创建一个会话令牌(即,session.Values[“authenticated”]==true),将其存储在cookie中(具有合理的到期日期),然后只需在
CreateUser
函数,在检查用户在数据库中不存在后,传递结构并保存它(对我来说这是显而易见的方式)
我假设我应该在回调处理程序中创建一个会话令牌(即,session.Values[“authenticated”]==true
),将其存储在cookie中(具有合理的到期日期),然后只需在预期登录用户的任何处理程序函数上检查if authenticated==true
?或者,对于管理员处理程序:如果admin\u user==true
这里有什么风险(如果有)假设我是通过HTTPS和使用安全cookie进行讨论的
对基本问题表示歉意:只是想掌握一下在w/OAuth中登录用户的“最佳实践”方法。OAuth标准中的
访问令牌
已经过期。它通常由授权服务器决定。在您的情况下,我假设您在授权服务器端
例如,阅读:
通常,承载令牌作为anOAuth 2.0[RFC6749]访问令牌响应的一部分返回给客户端。此类响应的一个例子是:
另请阅读以下内容中的访问令牌的概念:
访问令牌提供了一个抽象层,替换了不同的
使用单个
资源服务器可以理解令牌。这种抽象使
颁发比授权授予更严格的访问令牌
用于获取它们,以及删除资源服务器的需要
了解广泛的身份验证方法
因此,在您的情况下,我认为不需要“cookie”或“管理处理程序”。您只需为每个登录的用户生成访问令牌
&刷新令牌
,就像OAuth
规范所说的那样,并存储其到期日。您还可以提供与访问令牌
相关的哈希方法,以确保它是合法请求。例如,用户使用其访问令牌通过哈希和salt方法生成签名,将访问令牌和签名发送到服务器进行验证。阅读更多细节
此外,您不需要将这些令牌保存到数据库中,因为它们都是临时资源。您还可以将所有用户信息保存在内存中,并实现一个缓存层,定期将这些真正重要的信息保存到数据库中(我现在正在使用),以降低数据库压力。关于您的第一个问题,通常建议在单个事务中执行检查和插入。这取决于您使用的数据库,但这些通常被称为UPSERT
语句。在PLSQL中,它看起来有点像这样(根据口味进行修改):
关于你的第二个问题,通常HTTPS上的Secure
cookies就足够了。我设置了HttpOnly
选项,通常还设置了Path
选项
HttpOnly
意味着JS无法访问cookie(仅HTTP或HTTPS),而Path
选项允许您指定cookie的有效路径(在URL中)。我的问题可能不清楚:我正在实现OAuth2客户端,我正在尝试确定处理来自Google | GitHub |等的响应的“最佳实践”方法。一旦我获得一个包含用户数据(姓名、电子邮件、id、头像等)的JSON数组。我还试图确定当用户试图访问“私有”页面时对其进行身份验证的最佳方式;使用会话cookies似乎最适合这里;非常感谢。我正在使用RejectDB,它确实支持upserts(只是没有SQL语法):。谢谢你回答我的第二个问题:我的理解是,我真正使用cookie的唯一风险是重播攻击,但我计划有一个合理的到期日(7天)来限制这一风险。只要用户不能冒充管理员或其他用户,我就不会过分担心。我认为管理员用户的有效期短至30-60分钟可能是个好主意。他们可以造成更多的伤害!所以我得到赏金了吗?:-)如果你想等待一个更好的答案或更多的信息,这是很酷的。(我不得不等了12个小时才发布)
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"mF_9.B5f-4.1JqM",
"token_type":"Bearer",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
}
CREATE FUNCTION upsert_user(emailv character varying, saltv character varying, hashv character varying, date_createdv timestamp without time zone) RETURNS void
LANGUAGE plpgsql
AS $$;
BEGIN
LOOP
-- first try to update the key
UPDATE users SET (salt, hash) = (saltv, hashv) WHERE email = emailv;
IF found THEN
RETURN;
END IF;
-- not there, so try to insert the key
-- if someone else inserts the same key concurrently,
-- we could get a unique-key failure
BEGIN
INSERT INTO users(email, salt, hash, date_created) VALUES (emailv, saltv, hashv, date_createdv);
RETURN;
EXCEPTION WHEN unique_violation THEN
-- do nothing, and loop to try the UPDATE again
END;
END LOOP;
END;
$$;