익스프레스로 아이디 숨기기
21108 단어 javascriptexpressjsexpressnode
아이디를 왜 숨기나요?
제공하는 데이터 유형에 따라 ID를 숨기려는 데에는 여러 가지 이유가 있습니다.
예를 들어 API에 문서 공유(공개 Google 문서)가 포함된 경우 API에서 받은 ID를 단순히 증가시켜 사용자 파일을 열거할 수 있도록 허용하는 것은 좋지 않습니다.
또는 다른 사람들이 귀하가 보유한 사용자 또는 앱 수(또는 ID 오프셋을 사용하는 경우 시간이 지남에 따라 증가)를 확인하는 것을 원하지 않을 수 있습니다.
ID를 어떻게 숨깁니까?
성능상의 이유로 일반적으로 ID를 되돌릴 수 있기를 원하므로 ID를 직접 해싱하지 않는 것이 가장 좋습니다. 대신 사용자에게 보내기 전에 암호화하고 백엔드에서 액세스하려고 할 때 암호를 해독하려고 합니다.
이 게시물의 요점은 보안이 아니므로 hashids library 을 사용하겠습니다. 이것은 번호가 매겨진 ID에서 고유한 문자열을 생성하는 쉬운 방법을 제공합니다. Hashids는 결코 안전하지 않으며 ID를 난독화하는 간단한 방법일 뿐입니다.
코드에서 사용하는 방법은 다음과 같습니다.
const hashids = new Hashids("secret salt");
const encodedId = hashids.encode(42);
const [originalId] = hashids.decode(encodedId);
익스프레스 미들웨어
모든 공개 ID를 숨기고 싶다고 가정해 봅시다. 이는 요청 및 응답 본문의 모든
id
필드를 인코딩/디코딩한다는 의미입니다. user_id
와 같이 이것을 관계형 필드로 확장할 수도 있습니다. _id
로 끝나는 모든 필드에 동일한 작업을 수행합니다.Express에서 이를 달성하기 위해 두 개의 미들웨어를 만들고 싶습니다.
encodeMiddleware
및 decodeMiddleware
./** helper function to replace IDs inside object */
function replaceIds(obj, replaceFunc) {
if (obj == null) return obj;
for (const key of Object.keys(obj)) {
if (obj[key] == null) continue;
if (typeof obj[key] === "object")
obj[key] = replaceIds(obj[key], replaceFunc);
else if (key == "id" || (key.length >= 4 && key.endsWith("_id")))
obj[key] = replaceFunc(obj[key]);
}
return obj;
}
function encodeMiddleware(req, res, next) {
var _json = res.json;
res.json = (obj) => {
res.json = _json;
obj = replaceIds(obj, (v) => hashids.encode(v));
return res.json(obj);
};
next();
}
function decodeMiddleware(req, res, next) {
try {
req.query = replaceIds(req.query, (v) => hashids.decode(v)[0]);
req.body = replaceIds(req.body, (v) => hashids.decode(v)[0]);
} catch (e) {
console.error(`Could not decode id:`, e);
return res.sendStatus(404);
}
next();
}
encodeMiddleware
에서 우리는 응답이 항상 JSON이라고 가정하고 모든 id
발생을 인코딩된 버전으로 교체하여 수정합니다.decodeMiddleware
에서 우리는 데이터가 body
또는 query
에 있을 수 있고 모든 id
발생을 디코딩된 버전으로 대체할 수 있다고 가정합니다.이 두 가지 모두에 대해
req.url
를 비교하여 특정 끝점에 예외를 추가할 수 있습니다. 아니면 전 세계적으로 미들웨어를 사용하지 않을 수도 있습니다.또한 객체를 가져와서 제공된 함수를 사용하여 모두
ids
를 재귀적으로 대체하는 도우미 함수를 추가했습니다.예제 코드
이제 모든 것이 결합된 예가 있습니다.
const express = require("express");
const Hashids = require("hashids");
const hashids = new Hashids("secret salt", 6);
/** helper function to recursively replace ids inside object */
function replaceIds(obj, replaceFunc) {
if (obj == null) return obj;
for (const key of Object.keys(obj)) {
if (obj[key] == null) continue;
if (typeof obj[key] === "object")
obj[key] = replaceIds(obj[key], replaceFunc);
else if (key == "id" || (key.length >= 4 && key.endsWith("_id")))
obj[key] = replaceFunc(obj[key]);
}
return obj;
}
function encodeMiddleware(req, res, next) {
var _json = res.json;
res.json = (obj) => {
res.json = _json;
obj = replaceIds(obj, (v) => hashids.encode(v));
return res.json(obj);
};
next();
}
function decodeMiddleware(req, res, next) {
try {
req.query = replaceIds(req.query, (v) => hashids.decode(v)[0]);
req.body = replaceIds(req.body, (v) => hashids.decode(v)[0]);
} catch (e) {
console.error(`Could not decode id:`, e);
return res.sendStatus(404);
}
next();
}
const app = express();
app.use(express.json());
// we're using the middleware globaly here
app.use(encodeMiddleware);
app.use(decodeMiddleware);
// sample endpoints to demonstrate encoding, decoding
app.get("/get-id", (req, res) => {
res.json({ id: 5, name: "John" });
});
app.post("/send-id", (req, res) => {
console.log(req.body);
res.sendStatus(200);
});
app.listen(3000);
인코딩 및 디코딩
GET 끝점을 호출하면
id
및 name
를 사용하여 일부 JSON 데이터를 반환해야 합니다.> curl GET http://localhost:3000/get-id
{"id":"OPZexb","name":"John"}%
id
가 자동으로 인코딩된 것을 제외하고 우리가 한 일입니다. JSON 본문에서 _id
로 끝나는 항목을 반환하면 미들웨어가 자동으로 인코딩합니다.이제 인코딩된 id를 POST 끝점으로 전송해 보겠습니다.
> curl -X POST http://localhost:3000/send-id \
-H 'Content-Type: application/json' \
-d '{"id":"OPZexb"}'
...
[server log]: { id: 5 }
그리고 서버에서
{ id: 5 }
를 확인해야 합니다. 이는 미들웨어가 우리가 보낸 id
를 성공적으로 디코딩했음을 의미합니다. 마찬가지로 _id
를 포함할 수 있는 값을 보내면 자동으로 디코딩됩니다.마무리 메모
요청 또는 응답 본문에서 모든
id
를 찾아 필요에 따라 인코딩 또는 디코딩하는 글로벌 미들웨어를 추가할 수 있었습니다.프로덕션에서는 이 미들웨어가 타사 서비스의 웹훅에서 실행되는 것을 방지하기 위해 필터를 추가할 수 있습니다.
id
, _id
구문 자체를 사용할 수 있기 때문입니다.
Reference
이 문제에 관하여(익스프레스로 아이디 숨기기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/urosstok/hiding-ids-with-express-2lin텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)