如何解决每个 API 请求都会创建 Express-session 新会话
我正在使用 Spotify API,我正在尝试使用快速会话将用户访问令牌和刷新令牌保存到他们的会话中。我已经尝试了几乎所有我能找到的方法,但没有任何效果。
这是我的 app.js 代码,用于设置我的快速会话
var app = express();
var corsOptions = {
origin: 'https://jq-spotify.herokuapp.com',credentials: true
}
//Specify that connections from localhost:4200 (the client app) are allowed
app.use(cors(corsOptions));//http://localhost:4200
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
//app.use(cookieParser());
app.use(session({
name: 'sess-id',secret: 'jqSpotifySessionSecretToken',saveUninitialized: false,resave: false,store: new FileStore({}),proxy: true,cookie: {
sameSite: true,secure: true,maxAge: 3600000,path: '/'
}
}));
app.use('/',indexRouter);
这是我执行 API 调用的 index.js 文件。所以首先用户必须 /login,然后他被重定向到 /callback 保存会话(以及访问和刷新令牌)。之后,每当用户再次调用 API 时,express-sessions 都会创建一个新会话,并且不再保存访问/刷新令牌。
router.get('/login',function (req,res,next) {
var scopes = 'user-read-private user-read-email user-top-read';
res.redirect('https://accounts.spotify.com/authorize' +
'?response_type=code' +
'&show_dialog=true&client_id=' + my_client_id +
(scopes ? '&scope=' + encodeURIComponent(scopes) : '') +
'&redirect_uri=' + encodeURIComponent(redirect_uri));
});
router.get('/callback',next) {
var code = req.query.code || null;
var error = req.query.error || null;
if (error) {
console.error(error);
} else {
//we're probably good
const params = new URLSearchParams();
params.append('code',code);
params.append('redirect_uri',redirect_uri);
params.append('grant_type','authorization_code');
var headers = {
'Content-Type': 'application/x-www-form-urlencoded','Authorization': 'Basic ' + Buffer.from(my_client_id + ':' + my_client_secret).toString('base64')
};
fetch('https://accounts.spotify.com/api/token',{
method: 'POST',body: params,headers: headers,credentials: 'include',withCredentials: true
}).then(response => {
if (response.ok) {
return response.json();
} else {
//Could be better to redirect to an error page,but we'll go back to the client.
res.redirect(client_uri);
}
}).then(json => {
req.session.access_token = json.access_token;
req.session.refresh_token = json.refresh_token;
req.session.save();
res.redirect(client_uri);
}).catch(err => console.error(err));
}
});
router.get('*',next) {
next();
});
router.get('/me',next) {
makeAPIRequest('https://api.spotify.com/v1/me',req);
});
function refresh(req) {
const params = new URLSearchParams();
params.append('refresh_token',req.session.refresh_token);
params.append('grant_type','refresh_token');
var headers = {
'Content-Type': 'application/x-www-form-urlencoded','Authorization': 'Basic ' + Buffer.from(my_client_id + ':' + my_client_secret).toString('base64')
};
return fetch('https://accounts.spotify.com/api/token',{
method: 'POST',withCredentials: true
}).then(response => {
if (response.ok) {
return response.json();
} else {
throw ("Error refreshing token " + req.session.refresh_token + " " + refresh_token + " " + req.session.access_token+" " + access_token);
}
}).then(json => {
req.session.access_token = json.access_token;
req.session.refresh_token = json.refresh_token;
req.session.save();
return Promise.resolve();
}).catch(err => console.error(err));
}
function makeAPIRequest(url,req) {
var headers = {
'Content-Type': 'application/x-www-form-urlencoded','Authorization': 'Bearer ' + req.session.access_token
};
fetch(url,{method: 'GET',withCredentials: true}).then(response => {
if (response.ok) {
return response.json();
} else {
if (response.status == 401) {
refresh(req).then(() => {
return fetch(url,withCredentials: true}).then(response => {
if (response.ok) {
return response.json();
} else {
res.status(response.status).end();
}
});
});
} else {
res.status(response.status).end();
}
return null;
}
}).then(json => {
res.json(json);
}).catch(err => {
console.error(err);
});
}
我也在 Heroku 上托管我的服务器! 我再次用尽了我在互联网上能找到的所有东西,但没有任何效果。我很感激你的帮助,我已经坚持了一个星期!谢谢!
编辑:这是我的客户端调用 API 函数的方式
private sendRequestToExpress(endpoint: string): Promise<any> {
return this.http.get(this.expressBaseUrl + endpoint).toPromise().then((data) => {
return data;
});
}
解决方法
我会更改返回 Promise.resolve() 以便它会在 save() 之后执行:
}).then(json => {
req.session.access_token = json.access_token;
req.session.refresh_token = json.refresh_token;
req.session.save(function(err) {
return Promise.resolve();
});
}).catch(err => console.error(err));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。