Laravel-Websockets 中使用 SSL
因为手头一个 ws 的项目必须 PWA 化,所以对应的 Websockets 也要使用 SSL,由于 Laravel-Websockets 文档中关于如何支持 SSL 写得不是很详细,把 issue 里面相关的问题都看了一遍最后才解决了,记录一下
生成证书(*.example.com)
我使用的是 Let’s Encrypt 的免费通配符证书,生成步骤如下
# 先确保你的机器上装了 git cd /opt git clone https://github.com/certbot/certbot.git cd certbot ./certbot-auto certonly --manual --preferred-challenges=dns --email my@email.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d *.example.com -d example.com
然后按照提示为你的域名添加一个
TXT
的解析,用以验证你对域名的所有权,稍等片刻,让 DNS 缓存更新后验证成功即可生成 SSL 证书。修改配置文件
config/broadcasting.php
<?php $ssl_pusher_config = [ 'driver' => 'pusher', 'key' => env('PUSHER_APP_KEY'), 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), 'encrypted' => true, 'host' => '127.0.0.1', 'port' => 6001, 'scheme' => 'https', 'curl_options' => [ CURLOPT_SSL_VERIFYHOST => 0, CURLOPT_SSL_VERIFYPEER => 0, ] ] ]; $not_ssl_pusher_config = [ 'driver' => 'pusher', 'key' => env('PUSHER_APP_KEY'), 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), 'encrypted' => true, 'host' => '127.0.0.1', 'port' => 6001, 'scheme' => 'http' ] ]; return [ ... 'connections' => [ // 本地开发环境中不使用 SSL 'pusher' => env('APP_ENV') === 'local' ? $not_ssl_pusher_config : $ssl_pusher_config, ... ], ];
config/websockets.php
... 'ssl' => [ 'local_cert' => env('SSL_CERT', null), 'local_pk' => env('SSL_PK', null), 'passphrase' => env('JWT_SECRET', null), // 这个是可选项,作用类似于 JWT_SECRET, 用于加密 'verify_peer' => false, ], ...
.env
相关配置BROADCAST_DRIVER=pusher ... PUSHER_APP_ID=appid PUSHER_APP_KEY=websocketkey PUSHER_APP_SECRET=secret ... SSL_CERT=/etc/letsencrypt/live/example.com/fullchain.pem SSL_PK=/etc/letsencrypt/live/example.com/privkey.pem
前端调用
import Echo from 'laravel-echo'; let echor = new Echo({ broadcaster: 'pusher', key: process.env.MIX_PUSHER_APP_KEY, wsHost: window.location.hostname, wsPort: 6001, wssPort: 6001, disableStats: true, enabledTransports: ['ws', 'wss'], // 我用的是 jwt 进行验证的,如果你用的 session,请忽略此 auth: { headers: { Authorization: `${store.state.auth.token.token_type} ${store.state.auth.token.access_token}` } } }); export default echor;
部署
开放 6001 端口
sudo ufw allow 6001
让 websockets 持续运行,首先安装
supervisor
apt install supervisor
创建一个新的
supervisor
进程# 创建一个 websockets.conf touch /etc/supervisor/conf.d/websockets.conf # 填写如下 [program:websockets] command=/usr/bin/php /your-project-location/artisan websockets:serve numprocs=1 autostart=true autorestart=true user=sudo-www # 加载 websockets.conf supervisorctl update supervisorctl start websockets # 验证状态 supervisorctl status
完成~
本作品采用《CC 协议》,转载必须注明作者和本文链接
不用这么麻烦的 .用nginx 转发一下就行了 nginx 那里配置ssl 证书.
感谢楼主分享,这篇也可以参考
alex.bouma.dev/posts/installing-la...
感谢楼主分享,不过按照上面的配置,最后还是提示无法连接websockets:
使用的是宝塔环境,也是用supervisor建立进程,http协议下没有问题。 https折腾了好久也没实现,请教楼主可能是哪里出了问题呢?