Flow:
- User attempts to login via Spotify (OAuth), and grants access to our web app (nodejs).
accessToken
,refreshToken
,expires_in
andprofile
data is returned in exchange for the Authorization Code. (using Passport.js)accessToken
,refreshToken
and some other data is stored on mongoDb Atlas (cloud), forming a Document. (using mongoose)- The user logs out.
- The same user logs back in.
accessToken
,refreshToken
,expires_in
andprofile
data is returned in exchange for the Authorization Code.- The Document in the cloud database, gets updated.
We are using these access tokens to create API calls in our main application app.js
.
passport-setup.js: This file is 'required' in 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.findOneAndUpdate({
spotifyId: profile.id
}, {
$set: {
accessToken: accessToken,
refreshToken: refreshToken
}
}, {
new: true,
useFindAndModify: false
}).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);
})
}
})
})
)
Drawback:
The access token expires in an hour. To make more of the API calls, he need to re-login.
Update required for the application:
The refresh token should update the value of access token, in our database, every hour. (This should happen only for as long as the user stays logged in.)
This is what I'm aware of:
- Fetch access token using refresh token:
axios({
url: "https://accounts.spotify.com/api/token",
method: "post",
params: {
grant_type: "refresh_token",
refresh_token: // Please guide how to input the refresh token 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);
access_token = response.data.access_token;
token = "Bearer " + access_token;
console.log(token);
}).catch(function(error) {
console.log(error);
});
- For scheduling, we can use node-crone:
cron.schedule('*/59 * * * *', () => {
// Our task here, that we want to repeat 59th minute of every hour. We can also modify '59'. It's not necessary to have '59' only.
}
How to put the above two, together?
Where do we need to put the scheduled code - In passport-setup.js
or app.js
, or someplace else?