与Web小部件通信 - Meteor,React,Node [英] Communicating with a web widget-Meteor, React, Node

查看:91
本文介绍了与Web小部件通信 - Meteor,React,Node的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个聊天仪表板和小部件,客户应该可以将小部件放入他们的页面。一些类似的例子是内部通信漂移

I'm building a chat dashboard and widget with which a customer should be able to put the widget into their page. Some similar examples would be Intercom or Drift.

目前,主应用程序是用Meteor.js编写的(它的前端是React)。我写了< Widget /> 组件并将其抛入 / widget 目录。在这个目录中,我还有一个 index.jsx 文件,它只包含以下内容:

Currently, the "main" application is written in Meteor.js (it's front end is in React). I've written a <Widget /> component and thrown it inside a /widget directory. Inside this directory, I also have an index.jsx file, which simply contains the following:

import React from 'react';

import ......

ReactDOM.render(
  <Widget/>,
  document.getElementById('widget-target')
);

然后我设置一个webpack配置,其入口点为 index.jsx 当运行webpack时,在公共目录中吐出 bundle.js

I then setup a webpack configuration with an entry point at index.jsx and when webpack is run spits out a bundle.js in a public directory.

然后,只需包含脚本 div

<script src="http://localhost:3000/bundle.js" type="text/javascript"></script>
<div id="widget-target"></div>

几个问题:


  1. 这个实现有什么问题?他们的安全问题是否需要注意?之前链接的两个示例似乎都以一种或另一种形式使用iframe。

  2. 与主流星应用程序通信的最佳方式是什么? REST API?用Socket.io发出事件?小部件是一个聊天小部件,所以我需要来回发送消息。

  3. 如何为用户和小部件实现某种唯一标识符/用户身份验证?目前,小部件已预编译。


推荐答案

1这个实现有什么问题?他们的安全问题是否需要注意?之前链接的两个示例似乎都以一种或另一种形式使用iframe。

1 What is wrong with this implementation? Are their any security issues to be aware of? Both the examples linked earlier seem make use of an iframe in one form or another.

正如@JeremyK所提到的,你在iFrame中更安全。话虽如此,许多第三方(Facebook,GA,......)正在使用中间路线,包括对讲:

As @JeremyK mentioned, you're safer within an iFrame. That being said, there's a middle route that many third parties (Facebook, GA, ...) are using, including Intercom:


  • 问用户将捆绑的代码集成到其网页中。然后由您决定是否在其网站上引入安全漏洞。此代码将执行以下两项操作:

  • 负责设置iframe,其中服务的主要部分将会发生。您可以对其进行定位,设置样式等。这样可以确保iframe中发生的所有逻辑都是安全的并且您不会暴露。

  • 在您的客户网页和您的iframe之间公开一些API,使用窗口消息。

  • 主要代码(iframe代码)然后由第一个脚本异步加载,不包含在其中。

  • ask users to integrate your bundled code within their webpage. It's then up to you to ensure you're not introducing a security vulnerability on their site. This code will do two things:
  • take care of setting up an iframe, where the main part of your service is going to happen. You can position it, style it etc. This ensure that all the logic happening in the iframe is safe and you're not exposed.
  • expose some API between your customer webpage and your iframe, using window messaging.
  • the main code (the iframe code) is then loaded by this first script asynchronously, and not included in it.

例如,Intercom要求客户在其页面上添加一些脚本: https://developers.intercom.com/docs/single-page-app#section-step-1-include-intercom-js-library 非常小( https://js.intercomcdn.com/shim.d97a38b5.js)。这将加载额外的代码,用于设置iFrame并公开其API ,以便于交互使用iFrame,比如关闭它,设置用户属性等。

For instance Intercom ask customers to include some script on their page: https://developers.intercom.com/docs/single-page-app#section-step-1-include-intercom-js-library that's pretty small (https://js.intercomcdn.com/shim.d97a38b5.js). This loads extra code that sets the iFrame and expose their API that will make it easy to interact with the iFrame, like closing it, setting user properties etc.

2与主流星应用程序通信的最佳方式是什么? REST API?用Socket.io发出事件?小部件是一个聊天小部件,所以我需要来回发送消息。

2 What is the best way to communicate with my main meteor application? A REST API? Emit events with Socket.io? The widget is a chat widget, so I need to send messages back and forth.

你有三个选择:

  • Build your widget as an entire Meteor app. This will increase the size of the code that needs to be loaded. In exchange for the extra code, you can communicate with your backend through the Meteor API, like Meteor.call, get the reactivity of all data (for instance if you send a response to a user through your main Meteor application, the response would pop up on the client with no work to do as long as they are on the same database (no need to be on the same server)), and the optimistic UI. In short you've all what Meteor offers here, and it's probably going to be easier to integrate with your existing backend that I assume is Meteor.
  • Don't include Meteor. Since you're building a chat app, you'll probably need socket.io over a traditional REST API. For sure you can do a mix of both
  • Use Meteor DDP. (it's kind of like socket.io, but for Meteor. Meteor app use that for all requests to the server) This will include less things that the full Meteor and probably be easier to integrate to your Meteor backend than a REST API / socket.io, and will be some extra work over the full Meteor.

3如何为用户和窗口小部件实现某种唯一标识符/用户身份验证?

3 How can I implement some sort of unique identifier/user auth for the user and the widget?

这部分应该可以在客户网站上进行一些工作(与你的iframe相比) )这样您就可以在他的页面上设置cookie,并将该数据发送到您的iframe,该iframe将与您的服务器通信并识别用户。您使用 artwells:accounts-guest (基于 meteor:accounts-base )将依赖于你决定在你的iframe中包含Meteor。

This part should probably do some work on the customer website (vs in your iframe) so that you can set cookies on his page, and send that data to your iframe that's gonna talk to your server and identify the user. Wether you use artwells:accounts-guest (that's based on meteor:accounts-base) is going to depend on wether you decide to include Meteor in your iframe.

如果你的iframe中没有Meteor,你可以这样做:

If you don't have Meteor in your iframe, you can do something like:


  • 通过简单地在您的服务器上自行处理用户创建

const token = createToken();
Users.insert({ tokens: [token] });
// send the token back to your iframe
// and set is as a cookie on your customer website




  • 然后每次打电话给您的服务器,在您的iframe上:

  • let token;
    const makeRequest = async (request) => {
        token = token || getCookieFromCustomerWebsite();
        // pass the token to your HTTP / socket.io / ... request.
        // in the header of whatever
        return await callServer(token, request);
    };
    




    • 服务器中有一个设置用户的中间件。我看起来像:

    • const loginAs = (userId, cb) => {
        DDP._CurrentInvocation.withValue(new DDPCommon.MethodInvocation({
          isSimulation: false,
          userId,
        }), cb);
      };
      
      // my middleware that run on all API requests for a non Meteor client
      export const identifyUserIfPossible = (req, res, next) => {
        const token = req.headers.authorization;
        if (!token) {
          return next();
        }
        const user = Users.findOne({ tokens: token });
        if (!user) {
          return next();
        }
      
        loginAs(user._id, () => {
          next();
          // Now Meteor.userId() === user._id from all calls made on that request
          // So you can do Meteor.call('someMethod') as you'd do on a full Meteor stack
        });
      };
      

      这篇关于与Web小部件通信 - Meteor,React,Node的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆