taintObjectReference 让你可以防止将特定对象实例传递给像 user 对象这样的客户端组件。
experimental_taintObjectReference(message, object);要防止传递密钥、哈希或令牌,请参见 taintUniqueValue。
🌐 To prevent passing a key, hash or token, see taintUniqueValue.
参考
🌐 Reference
taintObjectReference(message, object)
使用对象调用 taintObjectReference 来将其注册到 React 中,作为不应直接传递给客户端的内容:
🌐 Call taintObjectReference with an object to register it with React as something that should not be allowed to be passed to the Client as is:
import {experimental_taintObjectReference} from 'react';
experimental_taintObjectReference(
'Do not pass ALL environment variables to the client.',
process.env
);参数
🌐 Parameters
message:如果对象被传递到客户端组件,你想要显示的消息。如果对象被传递到客户端组件,这条消息将作为抛出的错误的一部分显示。object:要被污染的对象。函数和类实例可以作为object传递给taintObjectReference。函数和类已经被阻止传递到客户端组件,但 React 的默认错误信息将被你在message中定义的内容替代。当一个特定的 Typed Array 实例作为object传递给taintObjectReference时,Typed Array 的任何其他副本都不会被污染。
返回
🌐 Returns
experimental_taintObjectReference 返回 undefined。
注意事项
🌐 Caveats
- 重新创建或克隆一个被污染的对象会创建一个新的未被污染的对象,该对象可能包含敏感数据。例如,如果你有一个被污染的
user对象,const userInfo = {name: user.name, ssn: user.ssn}或{...user}将创建新的未被污染的对象。taintObjectReference仅在对象未经过修改直接传递给客户端组件时防止简单错误。
用法
🌐 Usage
防止用户数据无意中到达客户端
🌐 Prevent user data from unintentionally reaching the client
客户端组件绝不应该接受携带敏感数据的对象。理想情况下,数据获取函数不应暴露当前用户不应访问的数据。有时在重构过程中会发生错误。为了防止这些错误在将来发生,我们可以在我们的数据 API 中“污染”用户对象。
🌐 A Client Component should never accept objects that carry sensitive data. Ideally, the data fetching functions should not expose data that the current user should not have access to. Sometimes mistakes happen during refactoring. To protect against these mistakes happening down the line we can “taint” the user object in our data API.
import {experimental_taintObjectReference} from 'react';
export async function getUser(id) {
const user = await db`SELECT * FROM users WHERE id = ${id}`;
experimental_taintObjectReference(
'Do not pass the entire user object to the client. ' +
'Instead, pick off the specific properties you need for this use case.',
user,
);
return user;
}现在,每当有人尝试将此对象传递给客户端组件时,都会抛出错误并附带传入的错误消息。
🌐 Now whenever anyone tries to pass this object to a Client Component, an error will be thrown with the passed in error message instead.
深入研究
🌐 Protecting against leaks in data fetching
如果你运行的服务器组件环境可以访问敏感数据,则必须小心不要直接传递对象:
🌐 If you’re running a Server Components environment that has access to sensitive data, you have to be careful not to pass objects straight through:
// api.js
export async function getUser(id) {
const user = await db`SELECT * FROM users WHERE id = ${id}`;
return user;
}import { getUser } from 'api.js';
import { InfoCard } from 'components.js';
export async function Profile(props) {
const user = await getUser(props.userId);
// DO NOT DO THIS
return <InfoCard user={user} />;
}// components.js
"use client";
export async function InfoCard({ user }) {
return <div>{user.name}</div>;
}理想情况下,getUser 不应暴露当前用户不应访问的数据。为了防止将 user 对象传递给下游的客户端组件,我们可以“污染”用户对象:
🌐 Ideally, the getUser should not expose data that the current user should not have access to. To prevent passing the user object to a Client Component down the line we can “taint” the user object:
// api.js
import {experimental_taintObjectReference} from 'react';
export async function getUser(id) {
const user = await db`SELECT * FROM users WHERE id = ${id}`;
experimental_taintObjectReference(
'Do not pass the entire user object to the client. ' +
'Instead, pick off the specific properties you need for this use case.',
user,
);
return user;
}现在,如果有人尝试将 user 对象传递给客户端组件,将会抛出一个带有传入错误信息的错误。
🌐 Now if anyone tries to pass the user object to a Client Component, an error will be thrown with the passed in error message.