V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
justdoit123
V2EX  ›  程序员

让 WebSocket 代替 HTTP 吧。。。。

  •  
  •   justdoit123 · 2016-01-10 00:49:27 +08:00 · 10716 次点击
    这是一个创建于 3241 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天看了 CSRF ,觉得好沉重啊。 突然有下面的设想,不知道有多少可行性,有很多地方不熟悉,例如 server 验证客户端可信等方面不懂。大家一起看下。

    让 WebSoket 替代 HTTP 进行通讯的设想如下:
    1. 浏览器要通过系统验证,通过验证的浏览器才能使用。( Chrome 、 Safari 、 Firefox...)
    2. 用户用某浏览器(设为 B1 ),访问某站点(设为 S1 ), S1 与 B1 之间就创建一条 WebSocket 连接。用户访问 S1 的任何页面、不管同时开启几个页面(都是使用 B1 浏览器), S1 与 B1 之间都有且仅有一条 WebSocket 连接作为通讯。
    3. 用户在电脑中安装了 N 个通过验证的浏览器,那么此用户与 S1 的连接数最大值即为 N ,保护服务器。
    4. 站点在与客户端(也就是浏览器)建立连接前,要验证浏览器的合法性。这点能否做到?

    CSRF 的难以防范主要是没有办法确认请求来自源页面,上面的方案是否就可以解决这样的问题?因为 ws 是有状态的连接,不需要 session 、不需要把身份信息保存在客户端,连接本身就是身份验证的象征,连接没法伪装(能伪装?没做过什么 C/S 应用,不确定 T_T )

    这可能会带来如下问题:
    1. SSO 可能没法进行了, SSO 是通过 cookie 作为信息媒介共享身份 token 的。
    2. 服务器压力问题。如果所有连接都是长时间活跃的那还没问题,如果一大堆僵死连接,连了之后都没操作,服务器在维持连接方面会耗费大量资源。这个是不是可以通过代理服务器来解决?即大量代理服务器专门用来承担连接保活的工作,请求则转发给处理服务器,再把结果转发给用户。
    3. 用户体验变差,没有 SSO 。同时也没有“记住我”的功能,每次关闭浏览器后连接都会关闭,会话结束,即退出登录。 能不能有类似记住密码、自动登录的机制来弥补下。。?
    4. 用户体验再差一点,网络不好导致连接断开是不是也要退出了。

    50 条回复    2016-05-01 23:27:28 +08:00
    justdoit123
        1
    justdoit123  
    OP
       2016-01-10 00:51:36 +08:00
    讨论讨论,是我想得太天真的部分,请指出吧。
    fy
        2
    fy  
       2016-01-10 00:53:47 +08:00
    楼主翻一下 http2
    然后翻一下异步 WebSocket 相关的资料
    oott123
        3
    oott123  
       2016-01-10 00:54:07 +08:00   ❤️ 1
    这就好比你说走路上班容易被车撞,那就买个直升飞机吧。
    hantsy
        4
    hantsy  
       2016-01-10 01:05:53 +08:00
    Websocket 只是一个标准,,,不局限于浏览器。我们之前项目已经有 Server 端与 Android 程序交互,简单的方式代替了笨重的消息推送。

    HTTP 是无状态, WebSocket 的连接太消耗性能,事件机制在 Web 上,多客户端情况下只有有少数情况才适应,全部 WS ,全维护所有客户端状态, 太天真了。当然现在有一些少数工具框架做这方面的,可能会用在股票,游戏等方面。
    dndx
        5
    dndx  
       2016-01-10 01:08:36 +08:00
    CSRF 明明有更简单的方法来防止, WS 本身并不是为了解决 CSRF 问题设计的,用起来有小题大做之嫌。
    justdoit123
        6
    justdoit123  
    OP
       2016-01-10 01:09:00 +08:00
    @fy http2 看到的貌似相关的是连接复用。但是能用来代替身份信息吗?另外, WebSocket 异步还在看。
    justdoit123
        7
    justdoit123  
    OP
       2016-01-10 01:10:33 +08:00
    @dndx 什么方法? 嗯嗯,知道 WS 不是为 CSRF 设计的。 哈哈~ 是想太大了点。
    justdoit123
        8
    justdoit123  
    OP
       2016-01-10 01:12:31 +08:00
    @hantsy 呃, android 的安装客户多的时候怎么办?
    ryd994
        9
    ryd994  
       2016-01-10 01:20:53 +08:00
    HTTP 套 WebSocket 套 HTTP2 ……
    FrankFang128
        10
    FrankFang128  
       2016-01-10 02:31:15 +08:00 via Android
    CSRF 是这么防的么?
    lincanbin
        11
    lincanbin  
       2016-01-10 09:30:26 +08:00
    1 、 CSRF 不难防
    2 、 ws 资源消耗爆炸
    3 、无法自动登录等等一堆问题你自己都知道了
    cmxz
        12
    cmxz  
       2016-01-10 09:51:41 +08:00
    没看懂为何 WS 可以防 CSRF
    Citrus
        13
    Citrus  
       2016-01-10 10:02:09 +08:00 via iPhone
    @dndx 应该说,完全不能用来防 CSRF
    @mistkafka 你确定你真的理解了 CSRF 的意义么。。。
    nbndco
        14
    nbndco  
       2016-01-10 10:32:58 +08:00
    虽然我不知道你这堆东西到底有什么意义
    不过你完全没有理解 CSRF
    你这样做完全不影响 CSRF
    gamexg
        15
    gamexg  
       2016-01-10 11:07:47 +08:00   ❤️ 1
    目前这些攻击其实都有简单的解决办法了,加 token 即可解决这个攻击。
    如果是用框架的话,很多都自带防护功能,根本不用担心这个问题。

    还有标准的浏览器发起的请求都带 Referer 字段,表明了请求来自哪个网站,你自己不做检查被攻击了那就没办法了。

    楼主自己实现一套协议,你需要所有的客户端都支持你的协议,这个难度只能说...
    这样还不如写个插件直接禁止网站向第三方发起请求呢。
    nbndco
        16
    nbndco  
       2016-01-10 12:09:31 +08:00
    @gamexg referer 没用的, https 就不发送了
    zado
        17
    zado  
       2016-01-10 12:38:22 +08:00   ❤️ 3
    WebSocket 设计得好并不会占用太多资源。我做的 http://www.zxxq.sinaapp.com/zxjb.html 能够长时间保持 10 万的连接,只有 1G 内存的 windows2008 服务器。
    imn1
        18
    imn1  
       2016-01-10 12:55:27 +08:00   ❤️ 2
    最重要一点: http 是短连接,无状态既是缺点也是优点, LZ 想过么
    chemzqm
        19
    chemzqm  
       2016-01-10 14:38:43 +08:00
    推荐一本书《浏览器网络技术》,我看了 2 遍,每次看都会有新的收获。
    stevegy
        20
    stevegy  
       2016-01-10 14:40:16 +08:00
    呵呵哒~~~楼主是不准备让我们这帮在企业防火墙和 http proxy 后面的人过不上幸福生活啊
    KIDJourney
        21
    KIDJourney  
       2016-01-10 14:45:38 +08:00
    CSRF 最常用的方法就是 token 和敏感操作二次认证吧。
    nmgwddj
        22
    nmgwddj  
       2016-01-10 14:48:18 +08:00
    搜索一下 Meteor
    hantsy
        23
    hantsy  
       2016-01-10 14:51:47 +08:00
    @nmgwddj Meteor 估计一般 JS 程序员也可以写出来的也是一团糟的东西,其中事件通知更新范围是技巧。
    chuxiwen
        24
    chuxiwen  
       2016-01-10 15:02:58 +08:00 via iPhone   ❤️ 1
    解决 CSRF , http 本身就可以做好。认证 token 也可以不放在 cookie 里。

    websocket 替代 http 是另外一个问题。主要原因还是浏览器的支持吧,而且现在的 websocket 的默认 handshake 还是通过 http 。

    Http2 刚出来,的推行估计要比 wehsocket 晚太多。

    web 技术统一一直都是行业难题,作为从业者只能适应。

    在一个完美的世界,应该会有一个 protocol 所有的浏览器都完美支持,这个 protocol 自己也应该是 轻量级,可扩展,支持 async ,也可以 stateful , bug free ,没有安全漏洞,有好用的 API ...
    hantsy
        25
    hantsy  
       2016-01-10 15:13:40 +08:00
    @KIDJourney CSRF 如果用 Spring 的话, Spring Security 很早就内置了。 JSF 2.2 也内置了,其它语言和技术框架估计也就是一个类似 Filter 的方案能够解决。
    500miles
        26
    500miles  
       2016-01-10 15:52:54 +08:00
    和 csrf 没什么关系吧。。。。

    现行标准下, websocket 连接的建立, 也是先通过 http 请求来的。。。

    别提替代这个词儿 。 。 。 。 。 。 。相得益彰啊 互相补充啊 多好!!!
    zonghua
        27
    zonghua  
       2016-01-10 16:25:28 +08:00 via iPhone
    http2 来啦, websocket
    justdoit123
        28
    justdoit123  
    OP
       2016-01-10 19:04:49 +08:00
    @chemzqm 这本书没找到, z.cn 、豆瓣京东等都没有。能给个链接吗?
    @500miles “替代”确实不好,进步改进
    justdoit123
        29
    justdoit123  
    OP
       2016-01-10 19:06:39 +08:00
    @500miles
    @nbndco
    @cmxz

    连接本身就可以代表身份,同一条连接没有办法被伪造,所以伪造请求也就变得不可能。当然,这里的请求是指带有身份信息的请求,涉及隐私安全。
    justdoit123
        30
    justdoit123  
    OP
       2016-01-10 19:08:16 +08:00
    @gamexg 哈哈~ 他们当然不会实现这些协议了。就是讨论讨论~ 先想嘛~
    justdoit123
        31
    justdoit123  
    OP
       2016-01-10 19:09:01 +08:00
    @imn1 嗯嗯。也是优势,双刃剑。
    justdoit123
        32
    justdoit123  
    OP
       2016-01-10 19:09:56 +08:00
    @stevegy 哪有这等恶意啊~ 讨论讨论 无忌哈~
    justdoit123
        33
    justdoit123  
    OP
       2016-01-10 19:10:50 +08:00
    @zado 收藏,体验体验
    justdoit123
        34
    justdoit123  
    OP
       2016-01-10 19:13:17 +08:00
    @chuxiwen 是放在 url 或隐藏域里吗嘛?
    nbndco
        35
    nbndco  
       2016-01-10 19:15:29 +08:00   ❤️ 2
    @mistkafka 你完全没有理解 CSRF 是什么。

    在你的假设下,每次用户打开浏览器后,需要重新登录网站之后在关闭浏览器前都可以使用(因为所谓可信的链接的已经建立了),其实这只需要 cookie 的 expires 设成空就可以了,不过你愿意折腾一下那就折腾一下。
    那么如果你现在先访问了 bank.com ,登录进去了,由于链接一直保持着,所以之后访问 bank.com 都可以被认证为你。接下来,你访问了 hot.xxx 网站,网站中有一个图片指向 src="http://bank.com/transfer?to=myaccount&amount=100000",会如何?浏览器直接使用之前建立的所谓可信链接访问 bank.com ,直接转账成功,和 cookie 是一模一样的。

    所以说你根本没有理解什么是 CSRF 。
    rannnn
        36
    rannnn  
       2016-01-10 19:21:52 +08:00
    https://www.meteor.com 不就是完全用 WebSocket 的框架吗
    loading
        37
    loading  
       2016-01-10 19:33:58 +08:00 via Android   ❤️ 1
    学得还不够深
    babytomas
        38
    babytomas  
       2016-01-10 19:39:34 +08:00
    判断浏览器不是可以看 UA 吗
    justdoit123
        39
    justdoit123  
    OP
       2016-01-10 19:41:58 +08:00
    @nbndco 我 x 嘞。愚钝了。
    chemzqm
        40
    chemzqm  
       2016-01-10 19:46:08 +08:00   ❤️ 1
    @mistkafka 英文名 《 High Performance Browser Networking 》, kindle 上有卖
    RangerWolf
        41
    RangerWolf  
       2016-01-10 20:12:33 +08:00   ❤️ 1
    @zado 请问有相关资料推荐学习吗? 或者介绍一下你的经验? 谢谢
    RangerWolf
        42
    RangerWolf  
       2016-01-10 20:14:56 +08:00
    @chemzqm 百度 google 都搜不到啊? “浏览器网络技术” 是书的全名?
    KIDJourney
        43
    KIDJourney  
       2016-01-10 21:01:45 +08:00
    @hantsy 是哒。一般在响应请求之前会过一层中间件,中间件会检查请求是否合法。
    martianyi
        44
    martianyi  
       2016-01-10 21:17:37 +08:00   ❤️ 1
    @RangerWolf 中文名《 Web 性能权威指南》
    strwei
        45
    strwei  
       2016-01-10 21:20:31 +08:00
    webRTC
    plantain
        46
    plantain  
       2016-01-10 21:33:30 +08:00
    搭车问:怎么用 CSRF 方式攻击 RESTful API (身份验证是 http only & secure 的 cookie; 没有 csrf token 机制)?
    looyao
        47
    looyao  
       2016-01-10 21:47:11 +08:00
    最近要做弹幕,感觉 WebSocket 很合适,不管是 WEB 端还是移动 App 端。
    不过不是所有场景都适合长连接,太耗资源。
    RangerWolf
        48
    RangerWolf  
       2016-01-11 14:30:24 +08:00
    @martianyi 原来就是这一本! 非常感谢!
    coderHuang
        49
    coderHuang  
       2016-01-11 16:47:21 +08:00
    实现的比较好的 RESTful 的 API 也可以避免 CSRF 的
    chuxiwen
        50
    chuxiwen  
       2016-05-01 23:27:28 +08:00 via iPad
    @mistkafka 放在 url 里应该可以。 hidden field 是很多 framework 的做法。也可以放在 http header 里。关键是只要不是浏览器自己本身会自动提交的地方(比如 cookies ), token 本身是有时效性一次性的 就可以了。有人的做法是有个单独 url 获取 csrf token ,之后服务器端设置只有指定的 domian 可以访问这个 url
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1051 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:25 · PVG 07:25 · LAX 15:25 · JFK 18:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.