问题是创建一个 Web 应用程序,该应用程序具有将其发送到我的 express 服务器的表单,从具有表单值的外部端点帖子生成 token ,使用来自外部域的 token 将帖子发送到外部端点,然后通过外部域的身份验证。
我能够在我的 Express 服务器上生成 token ,使用 token 向外部端点发送第二个帖子,并能够登录并查看 Express 服务器上的响应。
但是,当我尝试将 react 客户端重定向到外部域时,它显示一条超时消息。
我尝试使用 Axios 和 Fetch 从客户端发出第二篇帖子,然后重定向到外部域,但它给了我 CORS 错误,直到我打开 CORS chrome 插件,它仍然给我相同的超时消息。
我尝试在我的帖子调用中添加不同的 header 以允许重定向,但没有成功。
const router = require('express').Router();
const xml2js = require('xml2js');
const parseString = require('xml2js').parseString;
const request2 = require('request');
// const axios = require('axios')
var setCookie = require('set-cookie-parser')
var Cookies = require('js-cookie')
require('dotenv').config();
router.post('/sso', (req, response, next)=>{
// SETTING UP XML BODY FOR TOKEN GENERATOR
// USING TEMPLATE TO BUILD XML BODY FOR TOKEN GENERATOR
// SETTING UP POST TO TOKEN GENERATOR WITH XML TEMPLATE
// DECLARING TOKEN TO PASS TO SSO POST
// PROMISE FOR RESPONSE POST TO TOKEN GENERATOR
return new Promise((resolve)=>{
// ERROR CATCH BLOCK FOR POST TO TOKEN GENERATOR
try {
// POST TO TOKEN GENERATOR USING XML TEMPLATE
request2(TokenGenerator,
(err, res, body)=>{
// PARSE TOKEN GENERATOR BODY RESPONSE
// CONVERTING TO STRING SOAP BODY
// PARSING STRING INTO JSON TO TARGET TOKEN
// DECLARING TOKEN RESPONSE IN RES WITH TOKEN VALUE FROM POST TO TOKEN GENERATOR
// ASSIGNING IT TO GLOBAL VARIABLE
})
// TRYING POST FROM CLIENT HAS BEEN COMMENTED OUT
// // response.send(token)
// // next()
// SETTING UP POST TO PARTICIPANT SSO WITH TOKEN VALUE
const secondPostToSSO = {
method: 'POST',
url: 'externaldomain.com/sso.aspx',
followAllRedirects: true,
jar: true,
headers: {
'Content-Type': 'text/html'
},
form: {
'TOKEN': token
}
}
// POST TO PARTICIPANT SSO WITH TOKEN
request2.post(secondPostToSSO,(err, response2, body2)=>{
console.log(response2.request)
var cookies = setCookie.parse(response2, {
decodeValues: true,
map: true
})
console.log(cookies)
next()
})
})
} catch (e) {
console.error(`[FATAL ERROR] - KAPUT - ${e}`)
return res.redirect('/')
}
})
})
module.exports = router
我希望服务器 post 的输出将客户端重定向到我获取 token 的 externaldomain.com,并使用 token 进行 post 来验证客户端。结果应该是客户端已从我的网络应用程序登录到外部域。
最佳答案
几周前我已经解决了 CORS 问题并完成了申请,我想分享我的答案。
我解决 CORS 问题的方法是删除 React 并在同一端口上的服务器端使用简单的 HTML 客户端。我使用 npm 包 cors ( https://www.npmjs.com/package/cors )。我在 server.js
文件中添加了一行,如下所示:app.use(cors());
。
之后,我更新了 SSO 路由,以使用 response.send(token)
传递 token ,而不是使用 next()
。
一旦浏览器收到 token ,请记住,我在同一端口上有服务器和客户端,一旦从服务器收到 token ,客户端就会触发隐藏表单 POST。
瞧,解决了它。
API 路线:
const path = require('path');
const router = require('express').Router();
const app = require('express')
const xml2js = require('xml2js');
const parseString = require('xml2js').parseString;
const request2 = require('request');
const cors = require('cors')
require('dotenv').config();
// API routes
module.exports.routes = function (app) {
// POST API
app.post("/api/sso", (request, response, next)=>{
// SETTING UP XML BODY FOR TOKEN GENERATOR
const Template = {
// YOUR TEMPLATE
}
// USING TEMPLATE TO BUILD XML BODY FOR TOKEN GENERATOR
const builder = new xml2js.Builder()
const xml = builder.buildObject(Template)
// SETTING THE RIGHT ENVIRONMENT LINK FOR TOKEN GENERATOR BASED ON USER INPUT WITH IF STATEMENT
// SETTING UP POST TO TOKEN GENERATOR WITH XML TEMPLATE
const TokenGenerator = {
url: tokenGeneratorUrl,
method: 'POST',
headers: {
'Content-Type': 'text/xml'
},
body: xml
}
// DECLARING TOKEN TO PASS TO SSO POST
let TOKEN = ''
// PROMISE FOR RESPONSE POST TO TOKEN GENERATOR
return new Promise((resolve) => {
// ERROR CATCH BLOCK FOR POST TO TOKEN GENERATOR
try {
// POST TO TOKEN GENERATOR USING XML TEMPLATE
request2(TokenGenerator,
(err, res, body) => {
// PARSE TOKEN GENERATOR BODY RESPONSE
parseString(body,
(err, result) => {
// CONVERTING TO STRING SOAP BODY
const strBody = JSON.stringify(result['soap:Envelope']['soap:Body'])
// PARSING STRING INTO JSON TO TARGET TOKEN
// DECLARING TOKEN RESPONSE IN RES WITH TOKEN VALUE FROM POST TO TOKEN GENERATOR
// ASSIGNING IT TO GLOBAL VARIABLE
TOKEN = res.TokenResponse
})
// SENDING TOKEN TO CLIENT TO POST TO SSO
response.send(TOKEN)
})
} catch (e) {
console.error(`[FATAL ERROR] - KAPUT - ${e}`)
return res.redirect('/')
}
})
});
};
客户端隐藏表单:
<form style="display: none;" novalidate autocomplete="off" name="hiddenForm" id="hiddenForm" action="https://api.endpoint.com/route" method="POST" class="hiddenForm">
<input type="hidden" id="TOKEN" name="TOKEN" value="">
</form>
关于node.js - 如何使用 Express 服务器/ react 客户端在另一个域中 SSO 并重定向到另一个域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58609849/