I have a React front end with an express server that I’m using to send requests to the Figma REST API. The initial authentication piece appears to work. I call window.open from React to open my /auth route and complete the authentication in another window. The /callback route displays the access token in that window so the user can copy the value back into the React app where I’ll save it to localStorage so it can be used in other requests (this seemed a bit easier to me than messing around with session storage and cookies as I’m a noobie to this backed stuff).
My problem is that when I try to use the access token for GET /user, I’m getting a 403 invalid token error. Here what things look like:
Open the auth workflow from my React App:
const getToken = () => {
const params = `scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no,
width=500,height=600,left=100,top=100`
window.open('http://localhost:9000/auth', 'Login to Figma', params)
setShowLoginFields(true)
}
/auth route
router.get("/", (req, res) => {
// Store parameters in an object
const params = {
client_id: process.env.CLIENT_ID,
redirect_uri: "http://localhost:9000/callback",
scope: "library_analytics:read,files:read",
state: "howdy",
response_type: "code",
};
// Convert parameters to a URL-encoded string
const urlEncodedParams = new URLSearchParams(params).toString();
res.redirect(`https://www.figma.com/oauth?${urlEncodedParams}`);
console.log(urlEncodedParams);
});
The callback route renders the token in the window I opened.
/callback route
router.get("/", function (req, res, next) {
const { code } = req.query;
const body = {
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
redirect_uri: "http://localhost:9000/callback",
code: code,
grant_type: "authorization_code",
};
const options = { headers: { accept: "application/json" } };
axios
.post("https://www.figma.com/api/oauth/token", body, options)
.then((response) => {
res.render("callback", { token: response.data.access_token });
})
.catch((err) => res.status(500).json({ err: err.message }));
});
The user copies that back into the React app and triggers a call to the /userInfo route to get their user information while passing the token in the url.
React app:
const verifyToken = async () => {
const params = {
token: token
}
//Convert parameters to a URL-encoded string
const urlEncodedParams = new URLSearchParams(params).toString()
let url = `http://localhost:9000/userInfo?${urlEncodedParams}`
const result = await fetch(url, { mode: 'no-cors' }).then((response) => response.json())
console.log('Fetched from: ' + url)
console.log(result)
}
/userInfo route
const getUserData = async (token) => {
return await fetch("https://api.figma.com/v1/me/", {
headers: { Authorization: `Bearer ${token}` },
}).then((res) => res.json());
};
/* GET users route. */
router.get("/", async function (req, res, next) {
// Removes the /?token= prefix from the request url
let token = req.url.slice(8);
console.log(`the token is: ${token}`);
try {
const response = await getUserData(token);
console.log(response);
res.send(response);
} catch (e) {
res.send(e);
}
});
Any help would be greatly appreciated. Really banging my head on the desk with this one. Thanks!