node.js - Auth0 - 如何在自定义 API 或后端信任和保存用户信息?
问题描述
我试图弄清楚如何sub
在我的 API 服务器上为反应原生应用程序“信任”用户信息(例如姓名、电子邮件和声明等)。我在这里遵循了 auth0 提供的官方 react native 快速入门指南:
https://auth0.com/docs/quickstart/native/react-native/
而且我已经在网络上看到了这 4 或 5 种方式的迭代。是的,这很棒,我们有一个前端身份验证方法——我们在前端得到一个id_token
并access_token
返回给我们。很好,access_token
我完全理解,即我将其保存到设备上的本地存储中,将其添加到Authorization
标题中,并使用 jwt 中间件来保护路由(也由自定义 API 页面上的 auth0 提供):
var express = require('express');
var app = express();
var jwt = require('express-jwt');
var jwks = require('jwks-rsa');
var port = process.env.PORT || 8080;
var jwtCheck = jwt({
secret: jwks.expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: 'https://<myauth0domain>/.well-known/jwks.json'
}),
audience: '<myapiendpoing>',
issuer: '<myauth0domain>',
algorithms: ['RS256']
});
app.use(jwtCheck);
app.get('/authorized', function (req, res) {
res.send('Secured Resource');
});
app.listen(port);
现在终于到了我被困的地方:关于id_token
,我如何将任何用户 ID 信息保存到我的服务器并相信它真的是那个用户?我想保存他们的姓名和电子邮件等内容,因为我的应用程序还有一个用户设置表,用户可以在其中更改他们的个人资料信息。
当然,我不能只转发将id_token
其用作“受信任的”身份服务器端。在 auth0 服务器、设备和我的 API 之间存在连接步骤的那一刻,不良行为者可能会欺骗其中的值id_token
- 毕竟,它只是 JSON。
我当前的解决方案是从我的后端调用 auth0 的内置/userinfo
端点——你传递access_token
并获取用户信息,但显然这不是很高效。为了尝试避免性能问题,我这样做了一次以设置帐户信息,然后使用来自 的sub
声明(即用户 ID)access_token
来识别用户在任何以后的用户设置相关端点中是谁。声明通过JWT 中间件后就sub
可以信任了,对吧?
我能想到的唯一其他解决方案是将我的反应应用程序上的授权回调 URI 更改为我的 API 上的端点,而不是返回到反应本机应用程序的 URI,但我认为这意味着实现整个用户会话和快递中的护照故事。如果我想对 API 执行任何基于用户的操作,也许我必须这样做?
他们说 OAuth 让事情变得更容易,但在这一点上,我真的很困惑是否相信用户真的是他们所说的服务器端的人。事实上,id_token
在 UI 方面有什么意义呢?据我了解,id_token
仅出于纯粹展示目的而“信任”中的值。您永远不能将它们用作对服务器的请求中的标识键。
解决方案
答案是使用代码交换证明密钥 (PKCE)流程。在此流程中,您将生成代码验证者和挑战者,并接收可用于获取身份验证令牌、刷新令牌和 ID 令牌的一次性使用代码。这个请求可以在客户端完成。
使用这个一次性使用代码,我们可以从我们自己的服务器发出第二个请求,即实际令牌的请求。由于此请求是从您信任的服务器发出的(不是在客户端上,Auth0 也不允许您在客户端上发出请求!)我们可以相信返回的 id 令牌的内容没有被篡改。(即它是从您的 API 服务器到 Auth0 的机器对机器连接)
这也是查看用户是否已经存在的绝佳时间点(如果不存在,则使用 id 令牌的内容生成服务器端帐户或用户信息)。在理想情况下,用户只需进行一次身份验证(因此点击此端点一次),并且我们可以在不断更新授权令牌后使用我们安全保存在他们的帐户中的刷新令牌。
唯一的例外是如果刷新令牌本身过期,我们会要求他们再次进行身份验证。
编辑:
出于好奇,我在专门使用 React Native Expo 项目实现 PKCE 时遇到了一个额外的,虽然稍微不相关的问题。可以在此处和此处查看该问题的解决方案。
推荐阅读
- assembly - 在 LC3 中连接 3 个字符串
- django - Django 和 S3 Bucket aws Admin 静态文件
- python - Pandas - 添加与另一列同名的另一列
- c# - 在 C# 中分隔两个单独的字符串
- arrays - 如何启动结构的特定术语
- reactjs - 反应 onblur 不执行处理程序
- java - 无法将 ModelAttribute 中的 MultipartFile 与 Thymeleaf 一起使用
- c# - C# WPF 使用触发器将样式对象添加到 Datagrid 中的单元格
- php - Codecept Yii2 Docker 404
- android-studio - 如何使 Android Studio 不使用 compileOnly 依赖项来运行单元测试?