Как запланировать обновление маркера доступа (с помощью маркера обновления) в узле? (Пожалуйста, проверьте ответ.)

#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. Токен обновления должен обновлять значение токена доступа в нашей базе данных в течение первого часа с момента входа в систему; затем каждый последующий час до тех пор, пока пользователь остается в системе.
  3. (Необязательно) Если пользователь выходит из системы и снова входит в систему в течение одного часа с момента последнего маркера доступа, точка » 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);
 });