Spotify API 授权重定向次数过多
Spotify API Authorization redirects too many times
我正在尝试使用 Spotify API 并按照此处的授权说明进行操作:https://github.com/spotify/web-api-auth-examples/blob/master/authorization_code/app.js。
他们版本的Authorization代码直接在服务器代码中使用路由,但我想将Authorization分离到它自己的路由中。这是我的代码版本:
const authRouter = require("express").Router();
const config = require("../utils/config");
const request = require("request");
const querystring = require("querystring");
// Spotify client configurations
const client_id = config.CLIENT_ID;
const client_secret = config.CLIENT_SECRET;
const redirect_uri = config.REDIRECT_URI;
const stateKey = "spotify_auth_state";
//...
// @route GET /
// @desc Prompt User to Login into Spotify
authRouter.get("/", async (req, res) => {
try {
var state = generateRandomString(16);
res.cookie(stateKey, state);
// Request for user full name, profile image, and email address.
var scope = "user-read-private user-read-email";
// 1. Get the user's authorization to access data.
res.redirect(
"https://accounts.spotify.com/authorize?" +
querystring.stringify({
response_type: "code",
client_id: client_id,
scope: scope,
redirect_uri: redirect_uri,
state: state,
})
);
} catch {
console.log("error.");
}
});
// @route GET /callback
// @desc Spotify callback to request access and refresh tokens
authRouter.get("/callback", async (req, res) => {
try {
var code = req.query.code || null; // The authorization code returned by the first call.
var state = req.query.state || null;
var storedState = req.cookies ? req.cookies[stateKey] : null;
// Check the state parameter
if (state === null || state !== storedState) {
res.redirect(
"/#" +
querystring.stringify({
error: "state_mismatch",
})
);
} else {
res.clearCookie(stateKey);
const authOptions = getAuthOptions(
code,
redirect_uri,
client_id,
client_secret
);
// 2. Request an access token and refresh token
request.post(authOptions, function (error, response, body) {
if (!error && response.statusCode === 200) {
// Authorize successful. Access and Refresh Tokens granted.
var access_token = body.access_token,
refresh_token = body.refresh_token;
// Send the tokens to the client so the client can use them in requests to the Spotify API.
res.redirect(
"/#" +
querystring.stringify({
access_token: access_token,
refresh_token: refresh_token,
})
);
} else {
res.redirect(
"/#" +
querystring.stringify({
error: "invalid_token",
})
);
}
});
}
} catch {
console.log("error.");
}
});
module.exports = authRouter;
在我的 app.js 中:
const express = require("express");
const authRouter = require("./controllers/auth");
const cors = require("cors");
var cookieParser = require("cookie-parser");
// initialize app with Express to create client to communicate with Spotify
const app = express();
app.use(cors());
app.use(cookieParser());
app.use("/", authRouter);
module.exports = app;
现在,当我启动服务器时,我的浏览器 returns:"accounts.spotify.com redirected you too many times."。当我尝试以隐身模式启动我的服务器时,会出现 Spotify 登录提示。输入凭据后,它 returns: "accounts.spotify.com redirected you too many times."
我已经尝试清除我的 cookie 和缓存,但没有用。
此外,我已确认我的服务器重定向 URI 与我在 Spotify 应用程序设置中的重定向 URI 相同。
授权似乎陷入无限循环的原因是什么?
导致无限循环的原因是代码将访问和刷新令牌发送回客户端的地方:
// Send the tokens to the client so the client can use them in requests to the Spotify API.
res.redirect(
"/#" +
querystring.stringify({
access_token: access_token,
refresh_token: refresh_token,
})
);
因为我定义了以下路由:
authRouter.get("/", async (req, res) => {
访问和刷新令牌被重定向到登录页面,这将导致回调再次重定向到登录,形成无限循环。
我解决这个问题的方法是将访问和刷新令牌重定向到不同的组件,而不仅仅是 Spotify 示例代码中编码的 "/#" + query.string...
。
Spotify 的示例代码不会导致无限循环,因为他们为登录页面定义了 /login
路由,但我选择我网站的根作为登录页面,因为在我的情况下,身份验证应该是第一步.
我正在尝试使用 Spotify API 并按照此处的授权说明进行操作:https://github.com/spotify/web-api-auth-examples/blob/master/authorization_code/app.js。
他们版本的Authorization代码直接在服务器代码中使用路由,但我想将Authorization分离到它自己的路由中。这是我的代码版本:
const authRouter = require("express").Router();
const config = require("../utils/config");
const request = require("request");
const querystring = require("querystring");
// Spotify client configurations
const client_id = config.CLIENT_ID;
const client_secret = config.CLIENT_SECRET;
const redirect_uri = config.REDIRECT_URI;
const stateKey = "spotify_auth_state";
//...
// @route GET /
// @desc Prompt User to Login into Spotify
authRouter.get("/", async (req, res) => {
try {
var state = generateRandomString(16);
res.cookie(stateKey, state);
// Request for user full name, profile image, and email address.
var scope = "user-read-private user-read-email";
// 1. Get the user's authorization to access data.
res.redirect(
"https://accounts.spotify.com/authorize?" +
querystring.stringify({
response_type: "code",
client_id: client_id,
scope: scope,
redirect_uri: redirect_uri,
state: state,
})
);
} catch {
console.log("error.");
}
});
// @route GET /callback
// @desc Spotify callback to request access and refresh tokens
authRouter.get("/callback", async (req, res) => {
try {
var code = req.query.code || null; // The authorization code returned by the first call.
var state = req.query.state || null;
var storedState = req.cookies ? req.cookies[stateKey] : null;
// Check the state parameter
if (state === null || state !== storedState) {
res.redirect(
"/#" +
querystring.stringify({
error: "state_mismatch",
})
);
} else {
res.clearCookie(stateKey);
const authOptions = getAuthOptions(
code,
redirect_uri,
client_id,
client_secret
);
// 2. Request an access token and refresh token
request.post(authOptions, function (error, response, body) {
if (!error && response.statusCode === 200) {
// Authorize successful. Access and Refresh Tokens granted.
var access_token = body.access_token,
refresh_token = body.refresh_token;
// Send the tokens to the client so the client can use them in requests to the Spotify API.
res.redirect(
"/#" +
querystring.stringify({
access_token: access_token,
refresh_token: refresh_token,
})
);
} else {
res.redirect(
"/#" +
querystring.stringify({
error: "invalid_token",
})
);
}
});
}
} catch {
console.log("error.");
}
});
module.exports = authRouter;
在我的 app.js 中:
const express = require("express");
const authRouter = require("./controllers/auth");
const cors = require("cors");
var cookieParser = require("cookie-parser");
// initialize app with Express to create client to communicate with Spotify
const app = express();
app.use(cors());
app.use(cookieParser());
app.use("/", authRouter);
module.exports = app;
现在,当我启动服务器时,我的浏览器 returns:"accounts.spotify.com redirected you too many times."。当我尝试以隐身模式启动我的服务器时,会出现 Spotify 登录提示。输入凭据后,它 returns: "accounts.spotify.com redirected you too many times."
我已经尝试清除我的 cookie 和缓存,但没有用。
此外,我已确认我的服务器重定向 URI 与我在 Spotify 应用程序设置中的重定向 URI 相同。
授权似乎陷入无限循环的原因是什么?
导致无限循环的原因是代码将访问和刷新令牌发送回客户端的地方:
// Send the tokens to the client so the client can use them in requests to the Spotify API.
res.redirect(
"/#" +
querystring.stringify({
access_token: access_token,
refresh_token: refresh_token,
})
);
因为我定义了以下路由:
authRouter.get("/", async (req, res) => {
访问和刷新令牌被重定向到登录页面,这将导致回调再次重定向到登录,形成无限循环。
我解决这个问题的方法是将访问和刷新令牌重定向到不同的组件,而不仅仅是 Spotify 示例代码中编码的 "/#" + query.string...
。
Spotify 的示例代码不会导致无限循环,因为他们为登录页面定义了 /login
路由,但我选择我网站的根作为登录页面,因为在我的情况下,身份验证应该是第一步.