#node.js #mongodb #express #mongoose #passport.js
Вопрос:
Поток:
- Пользователь пытается войти в систему через Spotify (OAuth) и предоставляет доступ к нашему веб-приложению (nodejs).
accessToken
,refreshToken
,expires_in
иprofile
данные возвращаются в обмен на Код авторизации. (используя Passport.js)accessToken
,refreshToken
и некоторые другие данные хранятся в MongoDB Atlas (облако), формируя документ. (используя мангуста)- Пользователь выходит из системы.
- Тот же пользователь снова входит в систему.
accessToken
,refreshToken
,expires_in
иprofile
данные возвращаются в обмен на Код авторизации.- Документ, находящийся в облачной базе данных, не обновляется.
Мы используем эти токены доступа для создания вызовов API в нашем основном приложении app.js
.
Недостаток:
Если пользователь выходит из системы и снова входит в систему через час. Он больше не может совершать вызовы API. Срок действия токена доступа истекает через час.
Требуется обновление для приложения:
- Маркер доступа в нашей базе данных должен обновляться каждый раз, когда пользователь входит в систему. (В нашей базе данных не должно создаваться никаких новых «Документов» или «экземпляров» одного и того же пользователя.) [решено, проверьте ответ]
- Токен обновления должен обновлять значение токена доступа в нашей базе данных в течение первого часа с момента входа в систему; затем каждый последующий час до тех пор, пока пользователь остается в системе.
- (Необязательно) Если пользователь выходит из системы и снова входит в систему в течение одного часа с момента последнего маркера доступа, точка » 1 «не должна выполняться, а таймер для точки» 2 » не должен запускаться повторно.
passport-setup.js: Этот файл «требуется» в «app.js».
const passport = require("passport");
const SpotifyStrategy = require("passport-spotify").Strategy;
const keys = require("./keys");
const User = require("../models/user-model");
// Creating cookie
passport.serializeUser((user, done) => {
done(null, user.id);
})
// Acccessing the created cookie
passport.deserializeUser((id, done) => {
User.findById(id).then((user) => {
done(null, user);
})
})
passport.use(
new SpotifyStrategy({
// Options for Spotify Strategy
clientID: keys.spotify.clientID,
clientSecret: keys.spotify.clientSecret,
callbackURL: "/auth/spotify/redirect"
}, (accessToken, refreshToken, expires_in, profile, done) => {
// Passport callback function
console.log("Reached Passport callback function, inside of 'passport-setup.js'.");
// Check if user already exists in our database or if there is need to create a new one.
User.findOne({
spotifyId: profile.id
}).then((existingUser) => {
if (existingUser) {
console.log("User already exists in database. Latest record:");
console.log(existingUser);
done(null, existingUser);
} else {
new User({
displayName: profile.displayName,
email: profile._json.email,
spotifyId: profile.id,
accessToken: accessToken,
refreshToken: refreshToken
}).save().then((newUser) => {
console.log("New user created:");
console.log(newUser);
done(null, newUser);
}).catch((err) => {
console.log("Error occured: " err);
})
}
})
})
)
Я попытался обратиться к официальной документации по мангусту и посмотрел несколько учебных пособий в Интернете. Но все, с чем я вернулся, были ошибки. Следовательно, нужно обратиться за помощью. Я абсолютный новичок, буду признателен за любую помощь. 🙂
Ответ №1:
Для первого («1.») требуется обновление,
заменять
User.findOne({
spotifyId: profile.id
})
с
User.findOneAndUpdate({
spotifyId: profile.id
}, {
$set: {
accessToken: accessToken,
refreshToken: refreshToken
}
}, {
new: true,
useFindAndModify: false
})
Мне еще предстоит найти решение для других вопросов.
Текущий прогресс:
Я знаю, что мы можем использовать node-cron
это для планирования наших задач.
Ниже POST
приведен запрос на получение доступа от Spotify.
axios({
url: "https://accounts.spotify.com/api/token",
method: "post",
params: {
grant_type: "refresh_token",
refresh_token: refresh_token // I do not know how to input the database stored refreshToken here.
},
headers: {
Authorization: authorization,
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded"
}
}).then(function(response) {
// console.log(response.data);
// console.log(response.data.access_token);
let access_token = response.data.access_token;
let token = "Bearer " access_token;
console.log(token);
}).catch(function(error) {
console.log(error);
});