dgrubelic / vue-authenticate

Simple Vue.js authentication library
1.43k stars 252 forks source link

Twitter auth: popup is not closed and res.json() is not responded to the client after access_token received #209

Closed gouteru closed 3 years ago

gouteru commented 4 years ago

I have succeeded to get Twitter access_token and access_token_secret on my express app. but the popup window is not closed and the JSON response from express app is not returned to the client properly. The JSON response is shown on the popup. The client waits the response but nothings returned.

I have edited the example server.js to get access_token and accss_token_secret because I have been working on a kind of twitter emu app. Please help how I can get the response JSON.

Mac OS10.15.4 Chrome: 83.0.4103.61 vue: 2.6.12 client app url: http://127.0.0.1:8080/#/auth/OpenAuth express app url: http://127.0.0.1:4000 Callback URL of Twitter app on Twitter Developer http://127.0.0.1:4000/auth/twitter/callback

Here's serever.js I modified twitter auth like below.

I added the below callback function for twitter.

the first part for request token.

function twitterAuth(req, res) {
  if (!req.body.oauth_token) {
    oauthService.getOAuthRequestToken({ oauth_callback: req.body.redirectUri }, function (error, oauthToken, oauthTokenSecret, results) {
      if (error) {
        console.log('auth Twitter 1')
        res.status(500).json(error)
      } else {
        console.log('oauthToken: ', oauthToken)
        console.log('oauthTokenSecret: ', oauthTokenSecret)
        res.json({
          oauth_token: oauthToken,
          oauth_token_secret: oauthTokenSecret
        })
      }
  } 
app.get('/auth/twitter/callback', function(req, res, next){
  console.log('/auth/twitter/callback')
  let oauth_token = req.query.oauth_token
  let oauth_verifier = req.query.oauth_verifier
  console.log('oauth_token: ', oauth_token)
  console.log('oauth_verifier: ', oauth_verifier)

  if (req.query.oauth_token) {
    oauthService.getOAuthAccessToken(oauth_token, null, oauth_verifier, function (error, oauthAccessToken, oauthAccessTokenSecret, results) {
      if (error) {
        console.log('auth Twitter 2')
        res.status(500).json(error)
      } else {
        console.log('oauthAccessToken: ', oauthAccessToken)
        console.log('oauthAccessTokenSecret: ', oauthAccessTokenSecret)
        var verifyCredentialsUrl = 'https://api.twitter.com/1.1/account/verify_credentials.json'
        var parameters = {
          oauth_consumer_key: config.auth.twitter.clientId,
          oauth_token: oauthAccessToken,
          oauth_nonce: ('vueauth-' + new Date().getTime()),
          oauth_timestamp: timestamp.now(),
          oauth_signature_method: 'HMAC-SHA1',
          oauth_version: '1.0'
        }

        var signature = oauthSignature.generate('GET', verifyCredentialsUrl, parameters, config.auth.twitter.clientSecret, oauthAccessTokenSecret)

        Axios.get('https://api.twitter.com/1.1/account/verify_credentials.json', { 
          headers: {
            Authorization:  'OAuth ' +
              'oauth_consumer_key="' + config.auth.twitter.clientId + '",' +
              'oauth_token="' + oauthAccessToken + '",' +
              'oauth_nonce="' + parameters.oauth_nonce + '",' +
              'oauth_timestamp="' + parameters.oauth_timestamp + '",' +
              'oauth_signature_method="HMAC-SHA1",'+
              'oauth_version="1.0",' +
              'oauth_signature="' + signature + '"'
          }
        }).then(function (response) {
          console.log('FINISHED!!')
          // This json is displayed onto the popup window and never send back to the client function.
          res.json({
            access_token: oauthAccessToken,
            access_token_secret: oauthAccessTokenSecret,
            profile: response.data
          })
        }).catch(function (err) {
          console.log(err.response.data.errors)
          res.status(500).json(err.response.data.errors)
        })
      }
    })
  } else {
    next(new Error("you're not supposed to be here."));
  }
});

The client code is here.


import Vue from 'vue'
import VueAxios from 'vue-axios'
import VueAuthenticate from 'vue-authenticate'
import axios from 'axios'

Vue.use(VueAxios, axios)
Vue.use(VueAuthenticate, {
  tokenName: 'access_token',
  baseUrl: 'http://127.0.0.1:4000', // Your API domain
  providers: {
    twitter: {
      clientId: 'xxxxxxxxxxxxxxx',
      url: '/auth/twitter',
      redirectUri: 'http://127.0.0.1:4000/auth/twitter/callback'
      // redirectUri: 'http://127.0.0.1:4000/auth/twitter'
    }
  }
})

export default {
  methods: {
    authenticate: function (provider) {
      this.$auth.authenticate(provider).then(function (authResponse) {
        console.log('Auth Success!!')
        console.log('Provider: ', provider)
        console.log('authResponse: ', authResponse)
        // Execute application logic after successful social authentication
      })
    }
  }
}
literakl commented 3 years ago

Have you solved it?

gouteru commented 3 years ago

Not solved yet. but I got a workaround. Redirect from express app to my app's another page (not the same path of authenticate() is waiting for response), then store tokens included as URL query from express app onto localStorage then close popup window with a JS function, then popup close is handled by authenticate() and obtain tokens stored in localStorage.

dms-kim commented 2 years ago

make sure your Redirect Uri and Callback URL are the same.