javascript - 浏览器扩展(例如 “memonic”)如何将数据与特定用户相关联?

标签 javascript session cookies google-chrome-extension firefox-addon

假设您有一个“家庭”网站,用于某种“保存我最喜欢的剪报”服务,用户可以在其中注册帐户,然后将自己喜欢的报价单或其他文本的摘要保存到个人收藏中(这种网站的一个示例是“Memonic”:http://www.memonic.com/,我敢肯定。

第一个用例:用户访问他们喜欢的新闻站点,选择并复制一些文本,切换到加载了“主页”(剪切)站点的选项卡,粘贴到表单中,然后将所选文本保存到他们的帐户中。

第二个用例:用户访问新闻站点,选择文本,右键单击以选择一个菜单项,该菜单项将所选文本保存到其帐户中。他们不需要访问“主页”网站。这几乎就是Memonic的Firefox扩展所做的。

因此,在第一个用例(浏览器)中,假设基于PHP的体系结构,服务器从请求中从浏览器传递的cookie中识别用户。 Cookie包含该用户唯一的session_id,服务器用户从该cookie中找到 session 数据,其中包含user_id。然后使用user_id将记录插入数据库。

我的问题:在浏览器扩展程序中如何工作?我的理解是,扩展名不使用“ session ”或“cookies”,尽管我猜测有一种存储本地数据的方法。但是,如何将唯一的ID(以标识用户)从服务器传递给浏览器扩展?此唯一ID是应起源于服务器(如php的 session ID),还是客户端(浏览器插件)应将其生成并发送给服务器?

为了详细说明第二个用例:

  • 用户下载并安装浏览器扩展,但未注册
  • 用户可以免费注册10个“剪辑”,然后再注册
  • 帐户
  • 用户访问新闻站点,开始“剪切”,达到10,然后在扩展程序的工具栏中单击“注册”。网站上会弹出一个叠加层,其中包含一个iframe,其中包含注册表格。用户创建用户名和密码,单击提交。

  • 因此,现在,登录凭据(用户名和密码)已发送到“家庭”(裁剪)服务器,并且“家庭”服务器已经创建了一个带有user_id的新用户帐户,并存储在数据库中。在这一点上,浏览器扩展应该知道如何识别用户(一个user_id或一个session_id的等效物)……如何实现?

    ps-我真的只对Firefox和Chrome感兴趣

    最佳答案

    My question, how does this work in a browser extension? My understanding is that extensions do not use "sessions" or "cookies", although I'm guessing there is a way to store local data



    (我对addons.mozilla.org进行了代码和功能审查,因此对于Firefox方面的知识更为了解,但是在Chrome中应该差不多)

    好吧,有些插件利用了cookie和其他网络技术,但是大多数涉及这种扩展时,作者选择了这样的东西
  • 创建一个服务器端点,该端点可以通过XMLHttpRequest样式的AJAX通过代码轻松使用,通常是某种REST API端点。
  • 扩展程序通常可以访问本身就是XMLHttpRequest或类似XMLHttpRequest的某些API(例如Firefox Add-on SDKChrome])
  • 与用户互动后,扩展将发出XHR / Ajax调用以执行所需的任何操作,查询信息,注册帐户,登录用户,提交新数据等。

  • 扩展API通常提供多种存储和检索数据的方式,从纯文本文件,键值存储到关系数据库(WebSQL / IndexedDB),例如Firefox Add-on SDK simple-storage Chrome chrome.storage
    此外,可能会有API安全地存储登录凭据(例如 passwords module)

    由您决定要在浏览器中本地存储哪种数据,以及最适合哪种存储类型。

    通常,扩展可以完成网站可以完成的工作以及更多功能。 (在Chrome中,通过chrome.*扩展API,在Firefox中,您基本上可以完成Firefox可以完成的所有工作,而这是普通程序可以完成的所有工作)。

    But how would you pass a unique id (to identify a user) from the server to the browser extension?



    API如何以及是否保持(登录)状态完全取决于您,并取决于您(现有)的设计
  • 向每个请求发送用户:密码
  • 有一个登录API,它将设置适当的cookie或返回某种 session token ,这些 token 将在后续请求中使用。
  • 使用协议(protocol),例如OAuth2

  • Should this unique id originate on the server (like php's session id), or should the client (browser plugin) generate it and send it to the server?



    这取决于您,但对我而言,服务器生成了真正的唯一ID是有意义的,因为它通常了解仍然有哪些ID可用,而不是由浏览器扩展程序生成伪唯一ID(仍然有很小的冲突可能性) ids其他浏览器实例(其他用户)可能会并行生成。

    Second use case: A user visits the news site, selects the text, right clicks to choose a menu item which saves the selected text to their account. They aren't required to visit the "home" site. This is pretty much what Memonic's Firefox extension does.



    该插件将提供一个菜单项,单击时获取所选文本,然后通过后台API Ajax调用(在请求内或之前已进行身份验证的用户提供身份验证信息)将其发送给服务器。

    2) user is allowed 10 free "clippings" before registering an account


  • 该扩展名可以要求服务器(进行API调用)发出某种临时用户ID,并随每个“剪切”请求发送该ID。
  • 在10个此类“剪切”请求之后,服务器将返回错误,告诉扩展名“免费剪切”已用尽。
  • 此时,扩展程序将向用户询问“不再提供免费剪辑。注册帐户以获取无限剪辑”的内容,例如,通过在服务器上的新标签页(或其他辅助UI)中打开此类注册页面)。
  • 在打开页面时,扩展名可能已经将临时用户ID传递给了页面(例如,通过GET参数,或者通过设置cookie或请求数据或请求 header ),以便在成功注册后已经进行的“剪切”将与新的完整帐户相关联。
  • 该扩展程序还可以监视注册进度,以自动获取登录详细信息。

  • [Montioring registration] how is this accomplished?



    最简单的方法可能是附加a content-script并直接从DOM上抓取信息,或者让站点发布内容脚本随后将要处理的常规DOM事件。

    有些人还选择不通过常规网站+表单来完成整个注册工作,而是使用HTML来创建受扩展名控制的UI。然后,一旦用户单击注册按钮,扩展程序将读出注册字段,并进行另一个API调用以执行实际注册,服务器将向其回复成功或错误代码。成功后,扩展将记住登录信息并随后使用它。

    PS:
    这是使用Firefox Add-on SDK和上下文菜单项的完整示例扩展,单击该菜单项后将查询Web服务(API端点,此处无需身份验证),以将当前选项卡的TLD的注册者通知用户。它并没有完全转换为您的特定用例,而是一个很好的简单演示,用于显示您稍后可能需要的一些东西,并让您了解这种扩展的外观。
    var cm = require("sdk/context-menu");
    var notifications = require("sdk/notifications");
    var {Request} = require("sdk/request");
    var {Cc, Ci, Cu} = require("chrome");
    Cu.import("resource://gre/modules/Services.jsm");
    
    
    cm.Item({
      label: "Whois Registrant",
      contentScript: 'self.on("click", function (node, data) {' +
                     '  console.log("clicked", location.host);' +
                     '  self.postMessage(location.host);' +
                     '});',
      onMessage: function (domain) {
        domain = Services.eTLD.getBaseDomainFromHost(domain);
        Request({
          url: "http://www.restfulwhois.com/v1/" + encodeURIComponent(domain),
          headers: {"Accept": "application/json"},
          onComplete: function (response) {
            var msg;
            try {
                msg = "Registered via:\n" + JSON.stringify(response.json.registrant, null, 2);
            }
            catch (ex) {
                msg = "Failed - " + ex;
            }
            notifications.notify({
              title: domain,
              text: msg
            });
          }
        }).get();
      }
    });
    

    关于javascript - 浏览器扩展(例如 “memonic”)如何将数据与特定用户相关联?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20305010/

    相关文章:

    javascript - 使用 fs.readFileSync 从文件中读取行不会返回正确的字符串

    spring - Tomcat以管理员身份注销另一个用户

    Java Web 应用程序通过 cookie 保护授权

    javascript - 从另一个下拉列表填充下拉列表

    javascript - for 循环生成的二维 JavaScript 数组正在被最后一个循环结果覆盖

    javascript - 如果路由以斜杠结尾,则找不到 Next.js 页面

    cookies - Lynx 将其 cookie 存储在哪里?

    android - 在两个 webview 之间共享 session ?

    session - 用于 Django 中缓存 session 的 Redis 复制

    带有 Redis 的 Spring HttpSession 不保存 SESSION cookie 值