热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

EventSource中的HTTP授权标头(服务器发送事件)

如何解决《EventSource中的HTTP授权标头(服务器发送事件)》经验,为你挑选了3个好方法。

我需要为HTML5 EventSource设置一个Authorization标头.由于Websockets出现后服务器发送事件似乎被废弃,我找不到任何有用的文档.我已经发现的方法是在URL中传递授权数据......但我不喜欢这种方法.

我正在使用AngularJS并在$ httpProvider上设置拦截器,但是AngularJS没有拦截EventSource,所以我无法添加任何头.



1> 小智..:

此polyfill添加了Authorization Header支持:https://github.com/Yaffle/EventSource/

所以你可以这样做:

new EventSource("https://domain/stream", { authorizationHeader: "Bearer ..." });


关于此实现的注释:仔细阅读代码后,看起来它包装了带有计时器的XMLHttpRequest以完成类似EventSource的结果。不要批评,只是权衡服务器上的连接负载时要考虑的一点。
它不是polyfill,因为本机EventSource不支持用户定义的标头,因此当您的代码将使用本机EventSource时,您仅会得到隐藏的错误/错误。

2> srigi..:

EventSource没有用于将HTTP标头发送到服务器的API.当我使用SSE构建实时聊天时,我也在努力解决这个问题.

但是,如果您的SSE服务器与您的身份验证服务器是同一台服务器,我认为会自动发送COOKIE.



3> 小智..:

我意识到你的帖子已经超过一年了,但我发现自己在同一条船上,现在有了很好的答案.我希望这可以帮助某人,或者至少给他们一些想法......

COOKIEs似乎很容易,但如果有人阻止COOKIE会发生什么?我必须提示他们启用COOKIE才能使用该网站.在那时,他们开始怀疑他们是否可以信任该网站,因为他们因"安全原因"禁用了COOKIE.一直以来,出于安全考虑,我希望启用COOKIE!

使用AJAX,可以轻松地通过SSL POST验证数据,但这对SSE来说是不可能的.我看过许多帖子,然后人们说"只是使用查询字符串",但我不想通过以纯文本(example.com/stream?sessiOnID=idvalue)发送auth数据来破坏客户的安全性可以窥探.

在绞尽脑汁几个小时后,我意识到我可以在不影响客户身份验证数据的情况下实现整体目标.为了澄清,我在建立EventSource连接时没有发现一些POST方法,但它确实允许浏览器在每次重新连接时安全地传递带有EventSource的身份验证令牌.它们的关键是将所需的sessionID/token添加到lastEventID中.

用户可以像往常一样使用用户名/密码进行身份验证(或通过AJAX POSTing您保存在localstorage中的令牌).AJAX身份验证过程将使用短期令牌(在60秒内过期,或在使用时)传回一个JSON对象,该对象将保存在您所需的后端(例如:mySQL)以及更持久的令牌.此时,您启动SSE连接,如:

    qString = "?slt=" + "value-that-expires-within-seconds";
    streamURL = "http://example.com/stream.php";
    var streamSource = new EventSource(streamURL + qString);

    streamSource.addEventListener('auth',function(e) {
        var authStatus = JSON.parse(e.data);
        if (authStatus.session !== 'valid') {
            qString = "";
            streamSource.close();
        }
    })

在相应的PHP中你会做这样的事情:

        header("Content-Type: text/event-stream\n");
        ob_end_flush();
        ob_start();

        if (isThisShortLivedTokenValid($_GET["slt"])) {
            // The short-lived-token is still valid... so we will lookup
            // the value of the corresponding longer-lasting token and
            // IMMEDIATELY invalidate the short-lived-token in the db.
            sendMsg($realToken,'auth','session','valid');
            exit;
        } else if (isThisRealTokenValid($_SERVER["HTTP_LAST_EVENT_ID"])){
            while (1) {
                // normal code goes here
                // if ($someCOndition== 'newDataAvailable') sendMsg($realToken,'chat','msg-id','msg-content');
            }
        } else {
            http_response_code(404); // stop the browser from reconnecting.
            exit; //quit the PHP script and don't send anything.
        }


        function sendMsg($id, $event, $key, $val) {
            echo "{" . PHP_EOL;
            echo "event: " . $event . PHP_EOL;
            echo "id: $id" . PHP_EOL;
            echo 'data: {"' . $key . '" : "' . $val . '"}' . PHP_EOL;
            echo "}" . PHP_EOL;
            echo PHP_EOL;
            ob_flush();
            flush();
        }

        function isThisShortLivedTokenValid($sltValue) {
            //stuff to connect to DB and determine if the
            //value is still valid for authentication
            return $dbResult == $sltValue ? TRUE : FALSE;
        }

SSE连接短生命令牌,PHP验证短生命令牌并将其从数据库中删除,因此它永远不会再次使用AUTH.当您收到6位数的代码登录网上银行时,这有点类似.我们使用PHP来推送我们从数据库中检索的REAL令牌(稍后会过期)作为事件ID.Javascript不一定需要对此事件执行任何操作 - 服务器将自动结束连接,但如果您想要使用它,可以收听该事件.

此时,自PHP完成脚本以来,SSE连接已经结束.但是,浏览器将自动重新建立连接(通常为3秒).这次,它将发送lastEventId ...我们在删除连接之前设置为令牌值.在下一个连接上,此值将用作我们的令牌,应用程序将按预期运行.只要您在发送消息/事件时开始使用真实令牌作为事件ID,就不必断开连接.此标记值在浏览器接收时以及在与服务器的每个后续连接中通过SSL完全加密传输."以明文"传输的值在我们收到和使用它之后的几秒钟内就会过期,任何发现它的人都无法使用它.如果有人试图使用它,他们将收到404响应.

如果您已经将事件流ID用于其他目的,那么除非您连接auth-token和之前使用的值,否则它可能无法"开箱即用",并将其拆分为变量,因此它对其余部分是透明的.应用程序.就像是:

    // when sending data, send both values
    $sseID = $token_value . "_" . $previouslyUsedID;
    sendMsg($sseID,'chat','msg-id','msg-content');

    // when a new connection is established, break apart the values
    $manyIDs = explode("_", $_SERVER["HTTP_LAST_EVENT_ID"])
    $token_value = $manyIDs[0]
    $previouslyUsedID = $manyIDs[1]


推荐阅读
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • CentOS8.4 安装PHP7.4.25
    1、下载官网:https:www.php.netdownloads#cdmydata#wgethttps:www.php.netdistributionsphp ... [详细]
  • crossorigin注解添加了解决不了跨域问题_CORS与@CrossOrigin详解
    1、跨域的基本概念a、跨域的解释要了解跨域,首先需要知晓浏览器的同源策略,简单的说就是两个请求协议、端口、主机都相同,则两个请求具有相同的 ... [详细]
  • nvmw安装,用于控制node版本;
    之前一直使用的是nodev2.2.0版本,挺说新版本的node解决了npm安装插件产生文件夹结构过深的问题,所以就想更新试试;上网一看才发现,尼玛的node已经到了6.+版本了,好 ... [详细]
  • 前言对于从事技术的人员来说ajax是这好东西,都会使用,而且乐于使用。但对于新手,开发一个ajax实例,还有是难度的,必竟对于他们这是新东西。leo开发一个简单的ajax实例,用的是 ... [详细]
  • 表单提交前的最后验证:通常在表单提交前,我们必须确认用户是否都把必须填选的做了,如果没有,就不能被提交到服务器,这里我们用到表单的formname.submit()看演示,其实这个对于我们修炼道 ... [详细]
  • SSL协议、TLS协议,使用哪一种更安全?
    在金融银行业,保护机密信息的安全至关重要。由于财务记录完全通过在线数据库维护,因此实施保护客户、银行和金融机构免受黑客攻击的安全功能比以往任何时候都更加重要。安全套接字层(SSL) ... [详细]
  • 参加我们的第七届年度调查。有些来了又去了,但是今天有数百种Linux发行版运行良好。发行版,程序包管理器和桌面的结合为Linux用户创建了无数的定制环境。尽管存在一些共性,但我们也 ... [详细]
  • 本文分析和介绍了GLo ... [详细]
  • 一、域名解析记录说明记录类型A:用来指定域名的IPv4地址(如:8.8.8.8),如果需要将域名指向一个IP ... [详细]
  • R语言基础_数据导入&保存
    数据分析文件常用的储存格式为CSV(.csv)和EXCEL(.xlsx),其余文 ... [详细]
  • 【系列二】长连接,短连接及WebSocket介绍(含http1.0,1.1,2.0相关)
    前言上一节讲了长轮询和轮询及其实现,这节讲一讲长连接、短连接及webSocket,在讲这些之前,我们先来普及一下http相关的一 ... [详细]
  • Istio是一个用来连接、管理和保护微服务的开放平台。Istio提供一种简单的方式来为已部署的服务建 ... [详细]
  • Django3 使用 WebSocket 实现 WebShell
    △点击上方“Python猫”关注,回复“1”领取电子书剧照:《眷思量》作者:从零开始的程序员生活来源:https:www.c ... [详细]
  • webui之常用js操作(webui界面是什么)
    本文目录一览:1、web前端开发需要掌握的几个必备技术 ... [详细]
author-avatar
好kc好先生之家
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有