记录一下【Facebook 】expansionToken参数逆向
请求参数里面有个variables
{
"clientKey": null,
"expansionToken": "MjoxNzM4NDk5NjIwOgF1aZJ4Xi2w0IefR1OXX9CMCy5uza5mNDwBjY7bwuE7BGU461XN5VnKVN_WLk-wqOuTSTq7m-9NnPy4hTBUiIo8K-912v9ddBCBC_XlGtfVyanPflpSZcEWOFXGvEcrqOGxpkxGE9Fpoz9JvPHF2GdX924-kjYyi_GGFMODxheb039EgO52vlI_IRUaFLwBbtmRGxz0DQQUsHAG_SehdWiIH-T1jY175ZZYz49FdLvGOotNXSJZbLsD6cLVf-efB8BUrLoW5jkkb6efQOfoBG3EV3uFuPmP_pQf38RuTYVrXutYNslv7FqQe3zY-9hWWywMaJsimUCmaFuUq5ntE2wzX_m5A9ZEKRTrHUANccnUXzZ6lcoqZGhie_u8E8MK5byMMGl-P820OYkcKtQKTbK8IRs",
"feedLocation": "DEDICATED_COMMENTING_SURFACE",
"focusCommentID": null,
"repliesAfterCount": null,
"repliesAfterCursor": null,
"repliesBeforeCount": null,
"repliesBeforeCursor": null,
"scale": 1,
"useDefaultActor": false,
"id": "ZmVlZGJhY2s6OTQ0Njk2MzE0NDMwNDgyXzU5NjYwODEzNjMzMTAxOQ==",
"__relay_internal__pv__IsWorkUserrelayprovider": false
}
里面的expansionToken是动态参数
可以看到是在expansion_info里面
生成expansionToken的主要函数
function a(a, c, d, e) {
var f, h = n(function() {
return w(a, c)
}, [a, c]);
f = (a == null ? void 0 : (f = a.metadata) == null ? void 0 : f.plural) === !0;
f ? c == null || Array.isArray(c) || g(0, 13793, a.name, typeof c, a.name) : Array.isArray(c) && g(0, 57387, a.name, typeof c, a.name);
c == null || f && Array.isArray(c) && c.length === 0 || h != null || g(0, 37286, a.name, a.name, d, a.name, d);
var q = b("react-relay/relay-hooks/useRelayEnvironment")()
, r = p(function() {
return H(q, h)
})
, u = r[0]
, x = r[1]
, y = u;
r = y.environment;
if (!t(h, y.selector) || q !== y.environment) {
u = H(q, h);
x(u);
y = u
}
var z = o(!1);
m(function() {
z.current = h
}, [h]);
if (((u = a.metadata) == null ? void 0 : u.hasClientEdges) === !0) {
u = n(function() {
var d = B(y), b, f = [];
if (d == null ? void 0 : d.length) {
b = [];
for (var d = d, g = Array.isArray(d), h = 0, d = g ? d : d[typeof Symbol === "function" ? Symbol.iterator : "@@iterator"](); ; ) {
var i;
if (g) {
if (h >= d.length)
break;
i = d[h++]
} else {
h = d.next();
if (h.done)
break;
i = h.value
}
i = i;
i = F(q, a, c, i, e);
var j = i[0];
i = i[1];
b.push(j);
i != null && f.push(i)
}
}
return [b, f]
}, [y, q, a, c, e]);
var I = u[0];
u = u[1];
if (u.length)
throw (i || (i = b("Promise"))).all(u);
m(function() {
var a = j(q);
if (I == null ? void 0 : I.length) {
var b = [];
for (var c = I, d = Array.isArray(c), e = 0, c = d ? c : c[typeof Symbol === "function" ? Symbol.iterator : "@@iterator"](); ; ) {
var f;
if (d) {
if (e >= c.length)
break;
f = c[e++]
} else {
e = c.next();
if (e.done)
break;
f = e.value
}
f = f;
b.push(a.retain(f))
}
return function() {
for (var a = 0; a < b.length; a++) {
var c = b[a];
c.dispose()
}
}
}
}, [q, I])
}
if (A(y)) {
u = C(y);
if (u != null && u.length > 0)
throw (i || (i = b("Promise"))).all(u.map(function(a) {
return q.getStore().getLiveResolverPromise(a)
}));
if (s.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE || q !== r || !z.current || !t(z.current, h)) {
h != null || g(0, 57388);
u = h.kind === "PluralReaderSelector" ? h.selectors[0].owner : h.owner;
r = v(q, a, u);
if (r)
throw r.promise
}
}
D(q, y);
var J = o(null);
if (s.ENABLE_RESOURCE_EFFECTS && typeof k === "function") {
var K = l(function() {
var a = y
, b = E(y.environment, y);
if (b !== null) {
var c = b[0];
b = b[1];
if (c) {
x(b);
return null
}
a = b
}
return a
}, [y]);
k(function() {
var a = K();
if (a == null)
return {
subscribed: !1,
dispose: function() {},
selector: y.selector,
environment: y.environment
};
a = G(y.environment, a, x);
return {
subscribed: !0,
dispose: a,
selector: y.selector,
environment: y.environment
}
}, [], function(a) {
if (a.subscribed === !0 && y.environment === a.environment && y.selector === a.selector)
return;
else
a.dispose();
if (y.kind === "bailout")
return;
var b = K();
if (b == null)
return;
b = G(y.environment, b, x);
a.subscribed = !0;
a.dispose = b;
a.selector = y.selector;
a.environment = y.environment
}, [y], function(a) {
a.dispose(),
a.subscribed = !1
})
} else
m(function() {
var a = J.current;
if (a != null)
if (y.environment === a.environment && y.selector === a.selector)
return;
else
a.dispose();
if (y.kind === "bailout")
return;
a = y;
var b = E(y.environment, y);
if (b !== null) {
var c = b[0];
b = b[1];
if (c) {
x(b);
return
}
a = b
}
c = G(y.environment, a, x);
J.current = {
dispose: c,
selector: y.selector,
environment: y.environment
}
}, [y]),
m(function() {
if (J.current == null && y.kind !== "bailout") {
var a = G(y.environment, y, x);
J.current = {
dispose: a,
selector: y.selector,
environment: y.environment
}
}
return function() {
var a;
(a = J.current) == null ? void 0 : a.dispose();
J.current = null
}
}, []);
if (f) {
var L = c == null;
u = n(function() {
if (y.kind === "bailout")
return L ? null : [];
else {
y.kind === "plural" || g(0, 61167);
return y.snapshots.map(function(a) {
return a.data
})
}
}, [y, L])
} else
y.kind === "bailout" ? u = null : (y.kind === "singular" || g(0, 61166),
u = y.snapshot.data);
(s.LOG_MISSING_RECORDS_IN_PROD || 0) && (c != null && (u === void 0 || Array.isArray(u) && u.length > 0 && u.every(function(a) {
return a === void 0
})) && b("warning")(!1, "Relay: Expected to have been able to read non-null data for fragment `%s` declared in `%s`, since fragment reference was non-null. Make sure that that `%s`'s parent isn't holding on to and/or passing a fragment reference for data that has been deleted.", a.name, d, d));
return u
}