【免费下载链接】aonsoku
A modern desktop client for Navidrome/Subsonic servers built with React and Electron.
Aonsoku是一款基于 React + Electron 构建的现代桌面音乐客户端,专门用于连接Navidrome / Subsonic 服务器。本文带你从源码层面剖析它是如何与 Subsonic 服务器"对话"的:请求如何拼装、Token 认证机制如何用 MD5 加盐保护密码、登录流程如何握手协商版本,以及音频流媒体又是怎样复用同一套认证的。无需任何前置知识,跟着读就能看懂。
30秒速览:Aonsoku 的通信架构
Aonsoku 与服务器之间所有的通信,都收敛在一个薄薄的 API 层上,整体分为三层:
| 层级 | 目录 | 职责 |
|---|---|---|
| 数据查询层 | src/queries/ | 基于 React Query 的缓存与分页逻辑 |
| 业务服务层 | src/service/ | 按专辑、歌曲、电台等模块封装具体 API 调用 |
| 传输层 | src/api/ | 拼 URL、注入认证参数、解析 Subsonic 响应 |
所有业务模块最终都调用统一的服务门面 src/service/subsonic.ts,它把 albums、artists、songs、playlists、scrobble 等 12 个子服务聚合成一个subsonic对象,调用方只需:
subsonic.songs.getSong(id) subsonic.playlists.create(...)就像跟服务器说人话一样简单,而"把话翻译成协议"的脏活,全部由传输层完成。
Subsonic API 请求格式:每个请求都长什么样?
Subsonic 协议是一个基于 HTTP GET 的 REST API,Aonsoku 的传输层核心是 src/api/httpClient.ts。它做三件事:
1️⃣ 拼装 URL
getUrl 函数把任意 API 路径拼成标准格式:
{服务器地址}/rest/{接口名}?u=用户&t=令牌&v=1.16.0&c=Aonsoku&f=json2️⃣ 注入认证参数
每次请求都会自动附带一组"公参",这是理解 Subsonic 认证的关键 👇
| 参数 | 含义 | 示例 |
|---|---|---|
u | 用户名 | alice |
t | Token 令牌(MD5 哈希) | a1b2c3... |
s | 客户端盐值 salt | 40n50kuPl4y3r |
p | 密码(Password 模式下使用) | enc:xxxx |
v | 协议版本 | 1.16.0 |
c | 客户端名称 | Aonsoku |
f | 返回格式 | json |
3️⃣ 解析响应
浏览器抓取函数 负责解析 Subsonic 的标准响应包装——所有 JSON 响应都被包在一个subsonic-response字段里,同时从响应头x-total-count读取总数用于分页。
以获取随机歌曲为例,src/service/songs.ts 的写法非常直白:业务层只关心"要什么",认证、版本、格式等细节全部由httpClient自动处理。
Token 认证机制:密码是怎么变成令牌的?
这是全文最核心的部分 🎯 Subsonic 协议定义了两种认证方式,Aonsoku 在 src/types/serverConfig.ts 中用枚举定义:
AuthType.TOKEN // 令牌认证(默认,推荐) AuthType.PASSWORD // 密码认证(兜底方案)方式一:Token 认证(MD5 + 固定盐值)
Subsonic 规范规定:令牌 =MD5(密码 + 客户端盐值)。Aonsoku 的实现位于 src/utils/salt.ts:
saltWord = '40n50kuPl4y3r' // 固定盐值,随客户端发布 token = MD5(密码 + '40n50kuPl4y3r')这个盐值就像客户端的"暗号签名"——不同客户端使用不同盐值,服务器端可以为每个 Subsonic 账户生成多个令牌,分别授权给 Aonsoku、DSub 等其他客户端。
为什么不用明文传密码?因为 Token 是不可逆哈希,即使请求被截获,攻击者也无法还原你的真实密码;配合 HTTPS 使用,安全性更佳。
方式二:Password 认证(十六进制编码)
部分服务器可能禁用令牌,Aonsic 的兜底方案是把密码做十六进制编码后传输:
p = 'enc:' + 密码的十六进制串对应 genEncodedPassword,参数前缀enc:告知服务器"这是编码后的密码,请解码"。
认证参数的最终拼装
src/api/httpClient.ts 中的authQueryParams函数根据认证类型输出不同的参数对象:Token 模式返回{u, t, s}三元组,Password 模式返回{u, p}二元组,然后与版本、客户端名等公参合并,注入到每一个请求中——包括后续的音频流请求。
💡桌面端彩蛋:Aonsoku 支持构建期预置服务器配置。env-config.js.template 模板在打包时把SERVER_URL、APP_USER、APP_PASSWORD、APP_AUTH_TYPE注入window全局对象,src/utils/salt.ts 检测到有效配置后跳过登录页直接进入应用,适合"单用户专用客户端"的部署场景。
登录全流程:从输入密码到握手成功
打开 src/app/components/login/form.tsx,登录提交时依次执行三个动作:
第 1 步:探测服务器版本
queryServerInfo 使用dummy 假凭据调用/rest/ping.view(不需要真正登录),拿到协议版本、服务器类型,以及是否支持 OpenSubsonic 扩展。若版本低于1.15.0会弹出兼容性警告(可强制跳过)。
第 2 步:双认证尝试登录
saveConfig 是登录逻辑的灵魂——它按TOKEN → PASSWORD的顺序各试一次:
- 用密码分别生成 Token 和编码密码
- 调用 pingServer 请求
/rest/ping.view - 若服务器返回error code 30(版本错误),自动改用服务器声明的版本号重试一次
- 任何一种认证
status === 'ok'即视为登录成功,把 URL、用户名、认证后的令牌(注意:存的不是原始密码而是哈希值)、协议版本一并写入 Zustand 持久化存储
第 3 步:路由守卫持续守护
之后每次进入受保护页面,protectedLoader 都会重新 ping 一次服务器,配置缺失或服务器宕机时自动重定向回登录页,保证"永远不拿过期凭据去请求"。
音频流媒体:播放也走同一套认证
登录只是开始,真正的重头戏是放歌。看 src/app/components/player/player.tsx:
getSongStreamUrl(songId, maxBitRate, format, cacheBustToken)getSongStreamUrl 最终生成:
{服务器地址}/rest/stream?id=xxx&format=mp3&estimateContentLength=true&u=...&t=...&s=...关键点:音频流 URL 同样携带完整的认证参数,<audio>标签直接加载这个 URL 即可播放,无需额外的流媒体鉴权握手。此外还支持:
- 下载:getDownloadUrl 走
/rest/download,format=raw表示原始格式 - 播放上报:歌曲播完时调用 scrobble,向
/rest/scrobble上报id、time、submission参数,让服务器统计你的"最热歌曲" - 封面图:getSimpleCoverArtUrl 请求
/rest/getCoverArt?id=xxx&size=300,无封面时优雅降级到本地默认图
进阶细节:版本协商与 OpenSubsonic 扩展
现代 Subsonic 生态中,Navidrome 等服务器实现了OpenSubsonic 扩展(如歌词扩展songLyrics)。Aonsoku 在登录时就把服务器支持的能力探测一遍(queryServerInfo),存进extensionsSupported能力表,之后按需调用。
以歌词功能为例(src/service/lyrics.ts):如果服务器支持songLyrics扩展就优先从服务器取;若服务器没提供或歌词没有时间轴,则回退到 LRC 歌词源查找——一套能力探测 + 优雅降级的打法,这也是客户端应对异构 Subsonic 服务器的通用思路。
总结:新手可以记住的 5 个要点
- 一个入口:所有请求走
src/api/httpClient.ts,URL 格式统一为{url}/rest/{接口}?认证参数&业务参数 - 两种认证:Token 模式 =
MD5(密码 + 40n50kuPl4y3r)传t+s;Password 模式 =enc:十六进制传p,登录时自动择优 - 安全设计:本地持久化的是哈希令牌而非原始密码,截获请求无法还原密码
- 版本协商:登录即探测服务器版本,error code 30 触发自动重试,低于 1.15.0 提示不兼容
- 能力探测:通过 OpenSubsonic 扩展表按需启用歌词等功能,不支持则降级
理解了这套机制,你不仅看懂了 Aonsoku,也掌握了Subsonic API 集成的通用范式——换到 DSub、Amperfy 或其他 Subsonic 客户端,你会看到惊人相似的代码结构 🎵
想深入阅读?重点文件清单:
- API 传输层:src/api/httpClient.ts
- Token 生成:src/utils/salt.ts
- 登录握手:src/api/pingServer.ts + src/store/app.store.ts
- 服务门面:src/service/subsonic.ts
【免费下载链接】aonsoku
A modern desktop client for Navidrome/Subsonic servers built with React and Electron.
相关推荐
Excel-DNA部署指南:将.NET插件打包为XLL文件的完整步骤
Excel DNA部署指南:将.NET插件打包为XLL文件的完整步骤 Excel DNA是一款免费且易用的工具,可帮助开发者将.NET代码集成到Excel中,创
桌面应用插件系统B站番剧、弹幕、媒体库一站备齐:BiliTools 哔哩哔哩工具箱跨平台实操指南
B站番剧、弹幕、媒体库一站备齐:BiliTools 哔哩哔哩工具箱跨平台实操指南 BiliTools(哔哩哔哩工具箱)是一款免费开源、遵循 GPL 3.0 协议
桌面应用音视频Authelia认证机制深度剖析:WebAuthn与TOTP
Authelia认证机制深度剖析:WebAuthn与TOTP 本文深入分析了Authelia身份验证系统中的核心认证机制,重点剖析了WebAuthn安全密钥认证
后端认证鉴权身份认证单点登录
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考