Mastodon

在Headless环境完成Last.fm Web 授权

在Headless环境完成Last.fm Web 授权

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

lastfm banner

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

navidrome banner
  1. 提前DNS记录 lastfm.example.com A IPv4(关闭小黄云)
  2. 搭建最小回调服务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)
  1. 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
  1. 申请HTTPS证书
deactivate

sudo apt install -y certbot python3-certbot-nginx

sudo certbot --nginx -d lastfm.feddit.social

sudo nginx -t
sudo systemctl reload nginx
  1. 配置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
  1. 发起授权
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成功

  1. 用 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立即作废