在Headless环境完成Last.fm Web 授权
最近又决定玩一玩自托管音乐服务,不只是用spotidydownloader下载然后navidrome读取那么简单,还有spotdl、lastfm集成等等......

此篇文章主要记录下如何完成last.fm的web授权,此思想可以很好的移植到其他web 授权验证上。

- 提前DNS记录 lastfm.example.com A IPv4(关闭小黄云)
- 搭建最小回调服务Flask
mkdir -p ~/python/lastfm-callback
cd ~/python/lastfm-callback
python3 -m venv venv
source venv/bin/activate
pip install flask
nano app.py
from flask import Flask, request
app = Flask(__name__)
@app.route("/lastfm/callback")
def callback():
token = request.args.get("token")
if not token:
return "No token received", 400
return f"token = {token}"
if __name__ == "__main__":
app.run(host="127.0.0.1", port=8000)
- Nginx反向代理
sudo nano /etc/nginx/sites-available/lastfm
server {
listen 80;
server_name lastfm.example.com;
location /lastfm/ {
proxy_pass http://127.0.0.1:8000/lastfm/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
sudo ln -s /etc/nginx/sites-available/lastfm /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx- 申请HTTPS证书
deactivate
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d lastfm.feddit.social
sudo nginx -t
sudo systemctl reload nginx- 配置Last.fm Callback URL:https://lastfm.example.com/lastfm/callback
可在https://www.last.fm/api/accounts?suspend=1 查看API KEY & SHARED SECRET(注意,越往下越新)
API Docs | Last.fm
The world’s largest online music service. Listen online, find out more about your favourite artists, and get music recommendations, only at Last.fm

Login | Last.fm
The world’s largest online music service. Listen online, find out more about your favourite artists, and get music recommendations, only at Last.fm

- 发起授权
cd ~/python/lastfm-callback
source venv/bin/activate
python3 app.py在本地浏览器输入 http://www.last.fm/api/auth/?api_key=API KEY,替换API KEY为真实API KEY,完成授权,浏览器会跳转到https://lastfm.example.com/lastfm/callback?token=XXXXXXXX
获得Token成功
- 用 token 换取 session key(填写真实的YOUR_API_KEY、YOUR_API_SECRET、RECEIVED_TOKEN)
pip install requests
nano get_session.py
import hashlib
import requests
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
TOKEN = "RECEIVED_TOKEN"
params = {
"api_key": API_KEY,
"method": "auth.getSession",
"token": TOKEN,
"format": "json",
}
sig = "".join(k + params[k] for k in sorted(params) if k != "format")
sig += API_SECRET
params["api_sig"] = hashlib.md5(sig.encode()).hexdigest()
r = requests.get("https://ws.audioscrobbler.com/2.0/", params=params)
print(r.json())
python3 get_session.py成功后会返回session key长期有效,Token立即作废