node.js - 如何使用 Express 服务器/ react 客户端在另一个域中 SSO 并重定向到另一个域?

标签 node.js reactjs express single-sign-on saml

问题是创建一个 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/

相关文章:

javascript - 使用 WebdriverJS 测试 chrome 网上商店

mysql - 重构非阻塞nodejs do..while循环

reactjs - 如何在功能组件中的 React props 中使用泛型?

javascript - React JS setState(...) : Can only update a mounted or mounting component

javascript - NodeJs : Reference Error : (my own var) not defined

mongodb - 如何在 Node 蒙古语上使用 dropIndex() ?

node.js - 为什么这个 HTTP 请求在 AWS Lambda 上不起作用?

javascript - Node.js 使用 TypeScript 导出语法

javascript - React 中的类变量与 ES6

javascript - 使用 Passport JS 给出错误的请求