OPPO 设备空间绑定 NAS 授权失败问题
问题现象
OPPO 设备空间绑定 NAS (Nginx)时提示"密码错误"。同一账号在 NAS 官方 App 可以正常登录。
环境
- 网络:NAS 接在路由器下,通过 Nginx 网关对外提供服务
- NAS 端口:5666(HTTP)、5667(HTTPS)
- OPPO 设备空间版本:最新
排查过程
- 抓包发现设备空间请求的是
https://domain:5667/og.oauth2.v1.Oauth2Service/Authorize,走 gRPC 协议
- 最初在 Nginx 用 HTTP 代理将 5667 端口转发到 NAS 的 5666 端口(HTTP/1.1),授权失败
- 路由器直接映射 NAS 的 5667 端口后,授权成功
- curl 检查发现 NAS 5666 端口仅支持 HTTP/1.1,5667 端口支持 HTTP/2
- 根因:Nginx 将 gRPC 请求代理到 5666 端口时,协议被降级为 HTTP/1.1,gRPC 的状态码(trailers)丢失,导致认证结果无法正常返回
最终方案:grpc_pass
Nginx 从 1.13.10 开始内置了 ngx_http_grpc_module,专门代理 gRPC 流量。它会保持 HTTP/2 协议,正确处理 gRPC 的尾部状态码和流控。
思路是分而治之:gRPC 路径走 grpc_pass 重新加密到 NAS 的 HTTPS 端口 5667,保持 HTTP/2;其他请求走普通 proxy_pass 到 HTTP 端口 5666。
server {
listen 5667 ssl;
http2 on;
server_name nas.mydomain.xxx;
include snippets/ssl_cert.conf;
# gRPC 路径 → 直通 NAS HTTPS(保持 HTTP/2)
location ~ ^/(og|grpc)\. {
grpc_pass grpcs://192.168.x.43:5667;
grpc_ssl_verify off;
grpc_ssl_name nas.mydomain.xxx;
grpc_read_timeout 3600s;
grpc_send_timeout 3600s;
}
# 其他路径 → 普通 HTTP 代理
location / {
proxy_pass http://192.168.x.43:5666;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
proxy_request_buffering off;
}
}
证书统一由网关管理,gRPC 隧道通过 grpc_pass grpcs:// 重新加密到后端。既享受统一 SSL 终止的便利,又不牺牲 gRPC 协议完整性。
部署后一测——设备空间绑定成功,相册备份正常,文件浏览正常。