React应用本地对接Xero Accounting API的实现问题咨询
React对接Xero Accounting API授权流程调整
我正在本地React应用中对接Xero Accounting API,已搭建授权流程:先请求后端授权接口,再通过回调API获取用于数据调用的access_token。以下是我的代码,期望API返回响应:Access token obtained successfully, (Access Token)。
React前端组件代码
import { useLocation } from "react-router-dom"; import useXero from "../../hooks/useXero"; const SigninToXero: React.FC = () => { const location = useLocation(); const queryParams = new URLSearchParams(location.search); const authorizationCode = queryParams.get("code"); const handleAuthorizeClick = () => { window.location.href = "http://localhost:4000/authorize"; }; return <button onClick={handleAuthorizeClick}>Authorize Xero</button>; }; export default SigninToXero;
Express后端Xero路由代码
const express = require("express"); const xero = express.Router(); const schemas = require("../models/schemas"); const clientId = "xxx"; const clientSecret = "xxx"; const redirectUri = "http://localhost:4000/callback"; xero.get('/authorize', (_, res) => { // 重定向用户至Xero授权端点 const authorizeUrl = `https://login.xero.com/identity/connect/authorize?response_type=code&client_id=${clientId}&redirect_uri=${redirectUri}`; res.redirect(authorizeUrl); }); xero.get("/callback", async (req, res) => { const authorizationCode = req.query.code; // 用授权码交换访问令牌 const tokenResponse = await axios.post( "https://identity.xero.com/connect/token", null, { params: { client_id: clientId, client_secret: clientSecret, code: authorizationCode, grant_type: "authorization_code", redirect_uri: redirectUri, }, } ); const accessToken = tokenResponse.data.access_token; res.send("Access token obtained successfully", accessToken); }); module.exports = xero;
Node服务器主文件代码
const express = require("express"); const cors = require("cors"); const bodyParser = require("body-parser"); const router = require("./routes/router"); const xero = require("./routes/xero") const mongoose = require("mongoose"); require("dotenv/config"); const app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); const corsOptions = { origin: "*", credentials: true, optionSuccessStatus: 200, }; app.use(cors(corsOptions)); app.use("/", router); app.use("/", xero) const dbOptions = { useNewUrlParser: true, useUnifiedTopology: true }; mongoose .connect(process.env.DB_URI, dbOptions) .then(() => console.log("DB connected!")) .catch(err => console.log(err)) const port = process.env.PORT || 4000; const server = app.listen(port, () => { console.log(`Server is running on port ${port}`); });
问题修复及优化
- res.send用法错误:当前
callback路由中res.send("Access token obtained successfully", accessToken)的写法不符合Express规范,res.send仅接受一个主要内容参数,第二个参数不会被正确拼接。需改为字符串拼接形式:
res.send(`Access token obtained successfully, ${accessToken}`);
- 缺失axios依赖:后端路由代码中使用了axios但未引入,需在Xero路由文件顶部添加:
const axios = require('axios');
- 敏感信息硬编码风险:建议将
clientId、clientSecret这类敏感信息移至环境变量(如.env文件),通过process.env.CLIENT_ID、process.env.CLIENT_SECRET读取,避免代码泄露风险。
内容的提问来源于stack exchange,提问作者BEN_Stacey
相关产品推荐
相关产品推荐

