从客户端 JS 代码中使用 OAuth 授权代码流令牌是不是安全?

Posted

技术标签:

【中文标题】从客户端 JS 代码中使用 OAuth 授权代码流令牌是不是安全?【英文标题】:Is it safe to use OAuth authorization code flow tokens from the client JS code?从客户端 JS 代码中使用 OAuth 授权代码流令牌是否安全? 【发布时间】:2019-09-21 07:48:20 【问题描述】:

我正在阅读 Spotify Web API 文档,重点是授权指南。 他们为授权代码 OAuth2 流程提​​供了一些示例代码,但有些东西对我来说似乎不太正确。我对 OAuth 协议的了解有点有限,所以我不能确定。

事实上,他们在服务器端进行调用以获取访问和刷新令牌,但随后他们重定向到初始路由 将令牌作为 URL 参数传递,以允许从 JS 代码中使用。 下面是node.js服务器的代码:

[POST call to the token end-point to get the tokens]

[...]

// we can also pass the token to the browser to make requests from there
res.redirect('/#' +
    querystring.stringify(
        access_token: access_token,
        refresh_token: refresh_token
    )
);

然后,在前端 JS 上,他们使用这些令牌向 API 发出 HTTP 请求。他们甚至将令牌刷新作为 AJAX 调用。

我的问题是:这不是使用授权代码流的坏方法吗?是不是我修改了代码,把所有需要使用access token的API调用都迁移到后端,然后通过内部调用获取到后端接收到的信息?

【问题讨论】:

根据tools.ietf.org/html/rfc6749#section-1.3.2 你应该使用隐式授权 除非有特定的设计要求,否则不要将 OAuth 令牌从服务器发送到客户端。使用会话/cookies。会话/cookies 应加密或不透明。不要将刷新令牌发送给客户端。几乎总是使用三足 OAuth。几乎总是从不信任浏览器或客户端。详细信息取决于您需要从身份验证、授权和标识中获得什么以安全地向客户端提供服务。 【参考方案1】:

这在很大程度上取决于您的应用程序。如果您的用户使用您的网站并信任他的浏览器,那么将令牌保留在浏览器上应该不是问题。将令牌保存为浏览器上的 cookie 在安全方面与该用户登录到您自己的登录机制相同,该机制允许用户使用您的 api。

迁移它以使您的客户端要求服务器执行操作意味着您需要做一些事情:

为请求提供服务的服务器(也许您只想要一个执行 OAuth 的 web 应用,没有后端) 用户需要信任您的服务器以确保令牌安全 某种形式的授权,以确保只有一个用户可以使用您的 api 和令牌 您的服务器需要处理额外的请求,并且每个请求都会产生额外的延迟

【讨论】:

感谢您的回复,如果我不够清楚,请原谅。假设应用程序不提供登录机制,它只是使用OAuth让用户授权它访问他们的Spotify数据,那么在客户端使用令牌就可以了吗?就像@John 所说,我应该只将其设置为 cookie 而不是将其作为查询参数传递,对吗?如果我理解正确,SSL 足以防止任何可能的漏洞。 另外,说到第二种情况,每次从后端调用资源服务器API应该没有任何问题。 “用户需要信任您的服务器以确保令牌安全”是什么意思?我应该实现身份验证和用户登录功能吗? 如果您的应用程序根本没有登录机制,我建议您将令牌保留在客户端上,并将所有请求也发送到客户端上的 spotify api。如果可以,请不要将 cookie 保存在任何地方。如果您必须保存它,请为用户提供一种退出方式。如果您将令牌存储在服务器上,则保存令牌。这基本上就像他们帐户的密码,所以你不想把它放在不安全的地方。

以上是关于从客户端 JS 代码中使用 OAuth 授权代码流令牌是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

OpenId Connect 问题 - 授权代码流 (OAuth 2.0)

如何使用代码授权流在 Spring 应用程序中提取 Oauth2 访问令牌?

OAuth授权码流安全问题(授权码被黑客截获)

SPA 和 Spring Boot Rest Api 应用程序中具有授权代码授权类型的 OAuth2 流

授权代码流后,Spring OAuth2 服务器没有响应刷新令牌

Spring Oauth2 客户端凭据流示例