Websocket、Angular 2 和 JSON Web 令牌身份验证 [英] Websocket, Angular 2 and JSON Web token Authentication

查看:22
本文介绍了Websocket、Angular 2 和 JSON Web 令牌身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Angular 2 应用程序(用打字稿编码)有一个简单的身份验证方案:

My Angular 2 app (coded in typescript) has a simple authentication scheme:

  • 用户登录:
  • 服务器返回 JSON 网络令牌 (JWT) abc123...
  • 在每次 API 调用时,应用程序都会在 Authorization 标头中发送 JWT
  • 服务器验证 JWT 并授予访问权限

现在我想添加 websockets.我想知道如何在那里验证用户.由于我无法控制将哪些标头发送到 websocket 服务器 (WS),因此我无法发送 JWT.

Now I'd like to add websockets. I'm wondering how to authenticate the user there. Since I don't control which headers are sent to the websocket server (WS), I cannot send the JWT.

到目前为止我的想法(尚未实现):

My idea so far (not yet implemented):

  • 客户端打开websocket:let sock = new WebSocket('wss://example.com/channel/');
  • WS 服务器无需任何身份验证检查即可接受握手.此阶段提供标准 HTTP 标头.
  • 客户端侦听套接字上的 open 事件.套接字打开后:
    • 客户端发送带有 type='auth' 的消息 payload='JWT_VALUE'
    • Client opens websocket: let sock = new WebSocket('wss://example.com/channel/');
    • WS server accepts the handshake without any authentication check. Standard HTTP headers are available at this stage.
    • Client listens to the open event on the socket. Once the socket is open:
      • client sends a message with type='auth' payload='JWT_VALUE'
      • 如果验证失败,服务器断开套接字
      • 如果没有 isAuthenticated 的客户端发送任何其他类型的消息,服务器将断开套接字
      • If validation fails, server disconnects the socket
      • If a client without isAuthenticated sends any other type of message, server disconnects the socket

      2个问题:服务器资源可能被连接但从不发送JWT的客户端占用,如果客户端未通过身份验证,更简洁的解决方案会阻止握手.

      2 problems: server resources can be taken up by clients who connect but never send the JWT, and a cleaner solution would block the handshake if the client is not authenticated.

      其他想法:

      • 客户端可以在路径中发送 JWT:new WebSocket('wss://example.com/channel/<JWT>/')
        • pro:此信息在握手期间可用
        • con:该路径似乎不是 JWT 的合适"位置.特别是因为中间代理和访问日志会保存路径;在设计 HTTP API 时,我已经决定不在 u​​rl 中包含 JWT
        • pro:此信息可能在握手期间可用(不确定 IP)
        • con:猜测"客户端应该与 JWT 关联似乎非常不安全,因为客户端从来没有将它放在首位.这意味着,例如,欺骗受害者的 UA 并使用相同网络(代理、公共 wifi、大学内网...)的人将能够冒充受害者.
        • pro: this info may be available during the handshake (not sure about IP)
        • con: it seems horribly insecure to "guess" that a client should be associated with a JWT when the client never presented it in the first place. It would mean for instance that someone who spoofs the victim's UA and uses the same network (proxy, public wifi, university intranet...) will be able to impersonate the victim.

        你如何在 websockets 上验证客户端?假设用户已经通过 HTTP 登录,并且 Angular 2 应用有一个 JWT 令牌.

        How do you authenticate clients on websockets? Assume the user already logged in via HTTP and that the Angular 2 app has a JWT token.

        推荐答案

        我确定了以下协议:

        1. 客户端登录站点并接收身份验证令牌(JSON Web 令牌)

        1. Client logs into the site and receives an authentication token (JSON Web Token)

        GET /auth
        {
            user: 'maggie',
            pwd:  'secret'
        }
        
        // response
        { token: '4ad42f...' }
        

        2.经过身份验证的客户端请求一个 websocket 连接票

        2. Authenticated client requests a websocket connection ticket

        GET /ws_ticket
        Authorization: Bearer 4ad42f...
        
        // response: single-use ticket (will only pass validation once)
        { ticket: 'd76a55...', expires: 1475406042 }
        

        3. 客户端打开 websocket,在查询参数中发送票

        3. Client opens the websocket, sending the ticket in query param

        var socket = new WebSocket('wss://example.com/channel/?ticket=d76a55...');
        

        4. Websocket 服务器 (PHP) 然后在接受握手之前验证票据

        4. Websocket server (PHP) then validates the ticket before accepting the handshake

        /**
        * Receives the URL used to connect to websocket. Return true to admit user,
        * false to reject the connection
        */
        function acceptConnection($url){
            $params = parse_str(parse_url($url, PHP_URL_QUERY));
            return validateTicket($params['ticket']);
        }
        
        /** Returns true if ticket is valid, never-used, and not expired. */
        function validateTicket($ticket){/*...*/}
        

        这篇关于Websocket、Angular 2 和 JSON Web 令牌身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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