taintObjectReference를 사용하면 user 객체와 같은 특정한 객체 인스턴스를 클라이언트 컴포넌트로 전송하는 것을 방지할 수 있습니다.
experimental_taintObjectReference(message, object);키, 해시 또는 토큰이 전달되는 것을 방지하는 방법은 taintUniqueValue를 참고하세요.
레퍼런스
taintObjectReference(message, object)
클라이언트로 전달되지 않아야 할 객체를 taintObjectReference와 함께 호출하여 React에 등록합니다.
import {experimental_taintObjectReference} from 'react';
experimental_taintObjectReference(
'환경 변수는 클라이언트로 전달하지 마세요.',
process.env
);매개변수
-
message: 객체가 클라이언트 컴포넌트로 전달될 때 표시할 메시지. 객체가 클라이언트 컴포넌트로 전달될 때 발생하는 에러 객체에 포함되어 나타나는 메시지입니다. -
object: 오염(taint)될 객체. 함수와 클래스 인스턴스도object로서taintObjectReference에 전달될 수 있습니다. 함수와 클래스는 클라이언트 컴포넌트로 전달되지 않도록 이미 막혀있지만 React의 기본 에러 메시지 대신message에 설정한 메시지를 보여줄 수 있습니다. 타입 배열(Typed Array)의 인스턴스를object로서taintObjectReference에 전달하면 같은 타입 배열의 다른 인스턴스가 오염되지 않습니다.
반환값
experimental_taintObjectReference는 undefined를 반환합니다.
주의 사항
- 오염된 객체를 다시 작성하거나 복제하면 오염되지 않은 객체가 새로 만들어집니다. 새로 만들어진 객체는 민감한 데이터를 포함할 수 있습니다. 예를 들어, 오염된
user객체가 있다고 할 때,const userInfo = {name: user.name, ssn: user.ssn}혹은{...user}를 실행하면 오염되지 않은 새로운 객체를 작성합니다.taintObjectReference는 객체가 변경되지 않은 상태에서 클라이언트 컴포넌트로 그대로 전달되는 것만 방지합니다.
사용법
사용자 데이터가 의도하지 않게 클라이언트로 전달되는 것을 방지하기
클라이언트 컴포넌트에는 민감한 데이터를 담은 객체가 전달되어서는 안 됩니다. 이상적으로, 데이터 페치 함수는 현재 사용자가 접근할 수 없는 데이터를 노출하면 안 됩니다. 하지만 리팩토링 도중 가끔 실수가 발생하기도 합니다. 데이터 API에서 사용자 객체를 “오염(taint)“시켜서 이러한 실수를 방지할 수 있습니다.
import {experimental_taintObjectReference} from 'react';
export async function getUser(id) {
const user = await db`SELECT * FROM users WHERE id = ${id}`;
experimental_taintObjectReference(
'user 객체 전체를 클라이언트로 전달하지 마세요.' +
'필요하다면 일부 특정한 프로퍼티만 뽑아서 사용하는 것이 좋습니다.',
user,
);
return user;
}이제 누군가 이 객체를 클라이언트 컴포넌트로 전달하려고 하면 전달된 에러 메시지와 함께 에러가 발생됩니다.
Deep Dive
민감한 데이터에 접근할 수 있는 서버 컴포넌트 환경을 실행하고 있다면 객체를 그대로 전달할 때 주의를 기울여야 합니다.
// 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 객체가 클라이언트 컴포넌트로 전달되는 것을 방지하려면 사용자 객체를 “오염(taint)“시켜야 합니다.
// api.js
import {experimental_taintObjectReference} from 'react';
export async function getUser(id) {
const user = await db`SELECT * FROM users WHERE id = ${id}`;
experimental_taintObjectReference(
'user 객체 전체를 클라이언트로 전달하지 마세요. ' +
'필요하다면 일부 특정한 프로퍼티만 뽑아서 사용하는 것이 좋습니다.',
user,
);
return user;
}이제 누군가 user 객체를 클라이언트 컴포넌트로 전달하려고 하면 설정한 에러 메시지와 함께 에러가 발생합니다.