nicholastay / passport-discord

Passport strategy for authentication with Discord (discordapp.com)
ISC License
172 stars 55 forks source link

How can i refresh the profile data? #42

Closed MontejoJorge closed 3 years ago

MontejoJorge commented 3 years ago

If I need to refresh user data, how can I do it again without forcing the user to reload?

Example: the user logs in, then this user joins a guild x, but I still have his old guild list.

zignis commented 3 years ago

You need to reauthorize the user or use refresh token.

MontejoJorge commented 3 years ago

But how i do the new requests with the new acces token? @HexM7

zignis commented 3 years ago

You need to do a POST request and receive updated user object which will ultimately have updated guilds.

let params = new URLSearchParams(window.location.search); //Callback URL where the code will be present after authorization

if (params.has('code')) {
    let code = params.get('code');
    fetch('https://discord.com/api/oauth2/token', {
        method : 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: new URLSearchParams({
            client_id: 'YOUR_CLIENT_ID',
            client_secret: 'YOUR_CLIENT_SECRET',
            grant_type: 'authorization_code',
            code: code,
            redirect_uri: 'YOUR_REDIRECT_URL'
        })
    })
        .then((res) => res.json())
        .then(function(res) {
        return new Promise((resolve, reject) => {
          setInterval(() => {
            resolve(fetch('https://discord.com/api/oauth2/token/revoke', {
                method  : 'POST',
                headers : {
                    'Content-Type' : 'application/x-www-form-urlencoded'
                },
                body : new URLSearchParams({
                     client_id: 'YOUR_CLIENT_ID',
                    client_secret: 'YOUR_CLIENT_SECRET',
                    grant_type    : 'refresh_token',
                    refresh_token : res.refresh_token
                })
            }))
          }, 10000);
         })
        })
        .then((res) => res.json())
        .then(function(res) {
            fetch('https://discord.com/api/users/@me', {
                headers : {
                    authorization : `${res.token_type} ${res.access_token}`
                }
            })
                .then((res) => res.json())
                .then(function(res) {
                    const user = res.user; //Updated user object
                });
        });
}

Source

MontejoJorge commented 3 years ago

But using passport-discord isn't there a way to make it simpler? @HexM7

zignis commented 3 years ago

You may use external packages such as passport-oauth2-refresh as listed in the docs

var DiscordStrategy = require('passport-discord').Strategy
  , refresh = require('passport-oauth2-refresh');

var discordStrat = new DiscordStrategy({
    clientID: 'id',
    clientSecret: 'secret',
    callbackURL: 'callbackURL'
},
function(accessToken, refreshToken, profile, cb) {
    profile.refreshToken = refreshToken; // store this for later refreshes
    User.findOrCreate({ discordId: profile.id }, function(err, user) {
        if (err)
            return done(err);

        return cb(err, user);
    });
});

passport.use(discordStrat);
refresh.use(discordStrat);
MontejoJorge commented 3 years ago

I meant if passport-discord has some method to update the user directly, but well, even if this method is more rudimentary, it works for me, thanks for your time.

zignis commented 3 years ago

passport-discord does not have any method to automatically refresh the token AFAIK. Good luck!