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

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

现在我想添加WebSocket.我想知道如何验证那里的用户.因为我无法控制哪些头被发送到websocket服务器(WS),所以我无法发送JWT.

到目前为止,我的 idea (尚未实施):

  • 客户端打开websocket:let sock = new WebSocket('wss://example.com/channel/');
  • WS-server在不进行任何身份验证判断的情况下接受握手.标准HTTP头在这个阶段可用.
  • Client listens to the open event on the socket. Once the socket is open:
    • 客户端发送带有type='auth' payload='JWT_VALUE'的消息
  • WS-server希望套接字上的第一条消息的类型为auth.一旦收到,服务器就会读取有效负载,验证JWT_VALUE并设置isAuthenticated标志

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

其他 idea :

  • 客户端可以通过以下路径发送JWT:new WebSocket('wss://example.com/channel/<JWT>/')
  • 服务器可以读取客户端的IP+用户代理,并与HTTP服务器在发布JWT时创建的DB记录进行匹配.然后服务器将猜测谁正在连接

如何在WebSocket上验证客户端?假设用户已经通过HTTP登录,Angular 2应用程序具有JWT令牌.

推荐答案

我确定了以下协议:

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

GET /auth
{
    user: 'maggie',
    pwd:  'secret'
}

// response
{ token: '4ad42f...' }

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

GET /ws_ticket
Authorization: Bearer 4ad42f...

// response: single-use ticket (will only pass validation once)
{ ticket: 'd76a55...', expires: 1475406042 }

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

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

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

/**
* 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){/*...*/}

Typescript相关问答推荐

Typescript联合类型-字段类型覆盖

如何使用属性作为具有Generics的TypScript类中的类型守护?

处理API响应中的日期对象

有没有可能使用redux工具包的中间件同时监听状态的变化和操作

TypeScript Page Routing在单击时不呈现子页面(React Router v6)

如何提取密钥及其对应的属性类型,以供在新类型中使用?

使用TypeScrip根据(可选)属性推断结果类型

如何使默认导出与CommonJS兼容

使用2个泛型类型参数透明地处理函数中的联合类型

<;T扩展布尔值>;

类型TTextKey不能用于索引类型 ;TOption

函数重载中的不正确TS建议

正确使用相交类型的打字集

TYPE FOR ARRAY,其中每个泛型元素是单独的键类型对,然后在该数组上循环

重写返回任何

基于闭包类型缩小泛型类型脚本函数的范围

如何在TypeScript类成员函数中使用筛选后的keyof this?

传入类型参数<;T>;变容函数

Typescript泛型-键入对象时保持推理

Next 13 + React 18 createContext 类型的构建问题