{"record":{"id":"8b15fbf792916abd","repo":"hmjz100/LinkSwift","slug":"accesstokeninvalid","errorCode":"AccessTokenInvalid","errorMessage":"提示：<br/>访问令牌过期了，请刷新后重试~<br/>代码：AccessTokenInvalid","messagePattern":"提示：<br/>访问令牌过期了，请刷新后重试~<br/>代码：AccessTokenInvalid","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"（改）网盘直链下载助手.user.js","lineNumber":6643,"sourceCode":"\t\t\t\tif (cached.expires > Date.now()) {\r\n\t\t\t\t\tObject.assign(item, cached.data);\r\n\t\t\t\t\tproc++;\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\r\n\t\t\t\ttemp.glinks.splice(idx, 1); // 过期删除\r\n\t\t\t\treturn true;\r\n\t\t\t});\r\n\r\n\t\t\tfor (let i = 0; i < pending.length; i += size) {\r\n\t\t\t\t// 当前批次\r\n\t\t\t\tconst batch = pending.slice(i, i + size);\r\n\r\n\t\t\t\tawait Promise.all(batch.map(async (item) => {\r\n\t\t\t\t\tconst res = await base.post(config.$aliyun.api.getLink, { drive_id: item.driveId, file_id: item.fileId }, { \"Authorization\": token, \"X-Canary\": \"client=windows,app=adrive,version=v6.0.0\" });\r\n\r\n\t\t\t\t\tif (!res || !res.url || res.code) {\r\n\t\t\t\t\t\tif (res.code == \"AccessTokenInvalid\") throw new Error(\"提示：<br/>访问令牌过期了，请刷新后重试~<br/>代码：\" + res.code);\r\n\t\t\t\t\t\tif (res.code) {\r\n\t\t\t\t\t\t\tbatch.forEach(item => item.dlink = `获取下载地址失败，服务器说：${res.code}，刷新后再试试吧~`);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tthrow new Error(\"提示：<br/>获取下载链接失败，刷新网页后再试试吧~\");\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\t\tbatch.forEach(_item => {\r\n\t\t\t\t\t\tObject.assign(_item, res);\r\n\t\t\t\t\t\ttemp.glinks.push({ id: _item.file_id, expires: (Date.now() + 5 * 60 * 1000), data: res });\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tproc++;\r\n\t\t\t\t\t$doc.find(\".swal2-html-container\").html(`已获取 ${proc} / ${pending.length} 个链接`);\r\n\t\t\t\t}));\r\n\r\n\t\t\t\t// 批次间休息\r\n\t\t\t\tif (i + size < pending.length) await base.sleep(1000);\r","sourceCodeStart":6625,"sourceCodeEnd":6661,"githubUrl":"https://github.com/hmjz100/LinkSwift/blob/417ea5e28a3e1a90339710e17356e9fd22b8a34b/（改）网盘直链下载助手.user.js#L6625-L6661","documentation":"This userscript (网盘直链下载助手) throws this error when the Aliyun Drive (阿里云盘) backend replies with code \"AccessTokenInvalid\" for a get-link request. It means the Bearer token sent in the Authorization header is expired or revoked, so the server refuses to issue the download link. The script aborts the batch instead of silently writing a failed dlink, because a stale token requires a re-login/refresh rather than a retry with the same token.","triggerScenarios":"The script POSTs to config.$aliyun.api.getLink with an Authorization header containing a token that the Aliyun server has expired; res.code === \"AccessTokenInvalid\" in the batched Promise.all handler at line 6643.","commonSituations":"The user logged into Aliyun Drive a long time ago so the cached token expired; the user logged out and back in elsewhere invalidating the old token; the script refreshed the token in another tab and the current page holds a stale copy; Aliyun invalidated tokens server-side (e.g. after password change or security event).","solutions":["Refresh the Aliyun Drive page (F5) so the script picks up a fresh access token, then retry the download.","Log out of Aliyun Drive and log back in to obtain a brand-new token.","Clear the script's stored token (via Tampermonkey storage or the script's settings/reset) and re-authorize.","Check that the token being passed to base.post is the current one, not one captured earlier before a refresh."],"exampleFix":"// before: token captured once and reused\ntoken = base.getStorage('aliyun_token');\nawait base.post(config.$aliyun.api.getLink, data, { \"Authorization\": token });\n\n// after: detect invalid token, refresh, retry once\nconst res = await base.post(config.$aliyun.api.getLink, data, { \"Authorization\": token });\nif (res.code === \"AccessTokenInvalid\") {\n  token = await refreshToken(); // obtain new token before retrying\n  return base.post(config.$aliyun.api.getLink, data, { \"Authorization\": token });\n}","handlingStrategy":"retry","validationCode":"if (!token || Date.now() >= tokenExpiresAt) {\n  token = await refreshToken();\n}","typeGuard":"function hasValidToken(t) {\n  return typeof t === 'string' && t.length > 0 && Date.now() < getTokenExpiry(t);\n}","tryCatchPattern":"try {\n  await fetchLink(token);\n} catch (e) {\n  if (e.message.includes('AccessTokenInvalid')) {\n    const fresh = await refreshToken();\n    await fetchLink(fresh);\n  } else throw e;\n}","preventionTips":["Track token expiry timestamps and refresh proactively before batch downloads.","Refresh the netdisk page before long download sessions.","On AccessTokenInvalid, always re-auth rather than retrying with the same token.","Keep the userscript updated so token refresh logic tracks API changes."],"tags":["userscript","aliyundrive","auth","token-expired"],"backgroundTag":"invalid-access-token","analyzedSha":"417ea5e28a3e1a90339710e17356e9fd22b8a34b","analyzedAt":"2026-09-02T18:13:32.837Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}