我是 Koa.js 新手,我正在尝试使用 Spotify 创建一个简单的身份验证流程。这是我的代码:
import koa from "koa";
import querystring from "node:querystring";
const port = 54832;
const client_id = "myClientID";
const redirect_uri = `http://localhost:${port}/callback`;
const scope = "user-read-currently-playing";
export default function requestAuth() {
const server = new koa();
let response = {};
server.use(async (ctx) => {
const { url, method } = ctx.request;
if (method === "GET" && url === "/login") {
ctx.body = "You will be redirected to Spotify auth page";
ctx.redirect(
"https://accounts.spotify.com/authorize?" +
querystring.stringify({
response_type: "code",
client_id: client_id,
scope: scope,
redirect_uri: redirect_uri,
})
);
} else if (method === "GET" && url.includes("/callback")) {
if (!ctx.request.query.error) {
response.code = ctx.request.query.code;
} else {
console.log(ctx.request.query.error);
}
}
});
server.listen(port);
return response;
}
我想在用户访问
/login
URL 时将用户重定向到 Spotify 登录页面。但是,我没有重定向到 Spotify,而是被重定向到本地 URL http://localhost:54832/response_type=code&client_id=myClientID&redirect_uri=http%3A%2F%2Flocalhost%3A54832&scope=user-read-currently-playing
并在响应正文中获得“未找到”输出。
我处理重定向的方式是否有问题?这可能是我的服务器设置或 Koa.js 处理重定向的方式有问题吗?关于如何解决或修复此问题有什么建议吗?
早些时候我在 Express JS 上遇到了同样的问题。据我当时的理解,问题在于缓存,在这个框架中很难禁用它。这正是我转向 Koa JS 的原因。但由于在这种情况下问题仍然存在,我完全困惑
函数
requestAuth()
在处理任何 HTTP 请求之前立即返回一个对象,因此它始终为空且无用。
以下是您可以如何重构代码以使其更有效地工作,遵循 Koa 处理多个异步请求的典型用法
另存为
demo.js
import Koa from 'koa';
import Router from 'koa-router';
import bodyParser from 'koa-bodyparser';
import cors from '@koa/cors';
import axios from 'axios';
import { URLSearchParams } from 'url';
const app = new Koa();
const router = new Router();
const CLIENT_ID = "{your client id}";
const CLIENT_SECRET = "{your client secret}";
const PORT = 3000; // replace your port
const REDIRECT_URI = `http://localhost:${PORT}/callback`;
const SCOPE = 'user-read-currently-playing';
app.use(cors());
app.use(bodyParser());
const getToken = async (code) => {
try {
const response = await axios.post('https://accounts.spotify.com/api/token', new URLSearchParams({
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': REDIRECT_URI
}).toString(), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
auth: {
username: CLIENT_ID,
password: CLIENT_SECRET
}
});
return response.data.access_token;
} catch (err) {
console.error(err);
throw err;
}
};
router.get('/login', (ctx) => {
const redirect_url = `https://accounts.spotify.com/authorize?${new URLSearchParams({
response_type: 'code',
client_id: CLIENT_ID,
scope: SCOPE,
state: '123456',
redirect_uri: REDIRECT_URI,
prompt: 'consent'
}).toString()}`;
ctx.redirect(redirect_url);
});
router.get('/callback', async (ctx) => {
const code = ctx.query.code;
try {
const access_token = await getToken(code);
ctx.body = { 'access_token': access_token };
} catch (error) {
console.error(error.message);
ctx.status = 500;
ctx.body = { error: 'Failed to retrieve access token' };
}
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(PORT, () => {
console.log(`Listening on http://localhost:${PORT}`);
});
npm install koa koa-router koa-bodyparser @koa/cors axios
package.json
{
"type": "module",
"dependencies": {
"@koa/cors": "^5.0.0",
"axios": "^1.6.8",
"koa": "^2.15.3",
"koa-bodyparser": "^4.4.1",
"koa-router": "^12.0.1"
}
}
node demo.js
http://localhost:3000/login
将 3000 替换为你的端口号