837 字
4 分钟
获取onedrive token替换alist闭源api获取的token
众所周知,alist悄咪咪把项目卖了半年,今天才发消息通知用户。为了不用alist不开源的api(因为不知道那个api都会干什么),用gpt写了个python脚本
运行方法是你要有python环境。然后python alist-onedrive.py一下了。
感谢Falling42提供的办法,原贴:自动获取onedrive配置并添加alist存储
准备工作
去 https://portal.azure.com 用你想要挂载onedrive的E5或者个人账户登录
然后去 https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade 创建应用程序

注意
受支持的账户类型选 任何组织目录(任何 Microsoft Entra ID 租户 - 多租户)中的帐户和个人 Microsoft 帐户(例如 Skype、Xbox)
重定向URI 选 Web 是 http://localhost:53682/

然后记住这个 是 client_id

然后添加客户端密码

记住这个东西是 client_secret

然后去添加API权限 Files.ReadWrite.All offline_access Sites.Read.All

然后运行py脚本就行了
输入区可以写在or后面 也可以按照命令行提示输入
脚本会打开默认浏览器 接受权限

然后就成功了

遇到这个问题把代理全退出就好了

import http.serverimport webbrowserimport urllib.parseimport requestsimport jsonimport os
# ========== 输入区 ==========CLIENT_ID = input("🔑 请输入 Azure client_id: ").strip() or " client_id"CLIENT_SECRET = input("🔒 请输入 Azure client_secret: ").strip() or "client_secret"ALIST_REMARK = input("📝 Alist 挂载备注(如 OneDrive): ").strip() or "My OneDrive"ALIST_PATH = input("📂 Alist 显示路径(如 /onedrive): ").strip() or "/onedrive"ONEDRIVE_ROOT = input("📁 OneDrive 根路径(如 / 或 /某个子目录): ").strip() or "/"ALIST_URL = input("📁 Alist 服务地址: ").strip() or "http://localhost:5244"ALIST_USER = input("👤 Alist 管理员用户名: ").strip() or "admin"ALIST_PASS = input("🔑 Alist 管理员密码: ").strip() or "123456"
# ========== 常量区 ==========REDIRECT_URI = "http://localhost:53682/"SCOPES = "Files.ReadWrite.All offline_access User.Read Sites.Read.All"TOKEN_URL = "https://login.microsoftonline.com/common/oauth2/v2.0/token"CONFIG_OUTPUT_PATH = "alist_onedrive_config.json"
auth_code = None
class OAuthHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): global auth_code params = urllib.parse.parse_qs(urllib.parse.urlparse(self.path).query) if "code" in params: auth_code = params["code"][0] self.send_response(200) self.send_header("Content-type", "text/html; charset=utf-8") self.end_headers() self.wfile.write("<h1>✅ 授权成功!请返回终端。</h1>".encode("utf-8")) else: self.send_response(400) self.send_header("Content-type", "text/html; charset=utf-8") self.end_headers() self.wfile.write("<h1>❌ 授权失败,未获取到 code。</h1>".encode("utf-8"))
def start_server(): server = http.server.HTTPServer(('localhost', 53682), OAuthHandler) server.handle_request()
def get_alist_token(alist_url: str, username: str, password: str, otp: str = None) -> str: login_url = f"{alist_url}/api/auth/login" payload = { "username": username, "password": password } if otp: payload["otp_code"] = otp
res = requests.post(login_url, json=payload) if res.status_code != 200: raise Exception("❌ 无法连接 Alist 登录接口") data = res.json() if data.get("code") != 200: raise Exception(f"❌ 登录失败:{data.get('message')}") return data["data"]["token"]
def main(): print("🌐 打开浏览器进行 OneDrive 授权...") auth_url = ( f"https://login.microsoftonline.com/common/oauth2/v2.0/authorize" f"?client_id={CLIENT_ID}" f"&response_type=code" f"&redirect_uri={urllib.parse.quote(REDIRECT_URI)}" f"&scope={urllib.parse.quote(SCOPES)}" ) webbrowser.open(auth_url) start_server()
if not auth_code: print("❌ 未获取到授权码。") return
print("🔄 获取 refresh_token 中...") data = { "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "code": auth_code, "redirect_uri": REDIRECT_URI, "grant_type": "authorization_code" } response = requests.post(TOKEN_URL, data=data) if response.status_code != 200: print("❌ 获取 token 失败:") print(response.text) return
tokens = response.json() refresh_token = tokens.get("refresh_token") if not refresh_token: print("❌ token 响应中未找到 refresh_token。") return
# 获取 Alist 管理 token TWO_FA_CODE = input("📲 请输入两步验证码(如启用)[可留空]: ").strip() print("🔐 正在登录 Alist...") alist_token = get_alist_token(ALIST_URL, ALIST_USER, ALIST_PASS, TWO_FA_CODE)
# 构造符合 Alist API 要求格式的配置 payload = { "mount_path": ALIST_PATH, "order": 0, "remark": ALIST_REMARK, "cache_expiration": 30, "web_proxy": False, "webdav_policy": "302_redirect", "down_proxy_url": "", "order_by": "", "order_direction": "", "extract_folder": "", "enable_sign": False, "driver": "Onedrive", "addition": json.dumps({ "root_folder_path": ONEDRIVE_ROOT, "region": "global", "is_sharepoint": False, "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "redirect_uri": REDIRECT_URI, "refresh_token": refresh_token, "site_id": "", "chunk_size": 5, "custom_host": "" }, ensure_ascii=False) }
print("🚀 向 Alist 推送挂载配置...") api_url = f"{ALIST_URL}/api/admin/storage/create" headers = { "Content-Type": "application/json", "Authorization": alist_token } res = requests.post(api_url, json=payload, headers=headers)
if res.status_code == 200 and res.json().get("code") == 200: print("✅ 成功添加 OneDrive 挂载!请在 Alist 后台查看。") else: print("❌ 推送失败:") print(res.text)
# 同时写入配置文件备份 print(f"💾 正在写入配置到 {CONFIG_OUTPUT_PATH}...") with open(CONFIG_OUTPUT_PATH, "w", encoding="utf-8") as f: json.dump(payload, f, ensure_ascii=False, indent=2)
if __name__ == "__main__": main() 获取onedrive token替换alist闭源api获取的token
https://blog.useforall.com/posts/14/ 最后更新于 2025-06-11,距今已过 158 天
部分内容可能已过时
Lim's Blog