Working with basic Node OAuth redirect following

时光毁灭记忆、已成空白 提交于 2019-12-25 05:52:32

问题


Still confused about one point with node.

I’ve got a server running at http://localhost:3030 to listen for the hit from the redirect, but the redirect never comes.

How, in Node, do you have the request actually follow the redirects. And end up at
http://localhost:3030/?code=ccf3d214669645f594b59be14032e20d

Here is the link; In the browser it does end up in the right place
https://www.instagram.com/oauth/authorize/?client_id=8901edf0746b460489427434ba5d321e&redirect_uri=http://localhost:3030&response_type=code


回答1:


The authorization_code flow requires a browser, because the user have to be redirected to the third party web site to log in and authenticate your app, in this case that's the Instagram website. So you do need a browser to redirect you back to your redirect_url with the code parameter.

For that type of OAuth flow you can use Grant. You don't have to implement the OAuth flow by yourself. Just follow the basic example and replace facebook with instagram. As you can see you have a basic web server there and you have to navigate to the /connect/instagram route in your web browser. The only difference is that Grant will handle the heavy lifting for you, so you'll receive just the access_token at the end.

You can test the Instagram flow here.




回答2:


My first answer and comments are still valid, but I'm going to show you how you can automate the authorization process with nwjs.

First you need to enable the Implicit flow for your OAuth app - under the Security tab.

For the purpose of this demo I'm using http://localhost:3000/callback as redirect URI for my OAuth app. So you need to add it as additional redirect URL of your OAuth app. Also fill in all of the required credentials in authorization.html.

server.js

var fs = require('fs')
var path = require('path')
var http = require('http')
var url = require('url')
var qs = require('querystring')
var child = require('child_process')

var nw = null
var server = http.createServer()

server.on('request', function (req, res) {
  if (req.url == '/connect') {
    var dpath = path.resolve(__dirname)
    nw = child.spawn('nw', [dpath])
    res.end()
  }
  else if (req.url == '/callback') {
    var fpath = path.resolve(__dirname, 'token.html')
    var body = fs.readFileSync(fpath, 'utf8')
    res.writeHead(200, {'content-type': 'text/html'})
    res.end(body)
  }
  else if (/^\/token/.test(req.url)) {
    var uri = url.parse(req.url)
    var query = qs.parse(uri.query)
    console.log(query)
    nw.on('close', function (code, signal) {
      console.log('NW closed')
    })
    nw.kill('SIGHUP')
    res.end()
  }
})

server.listen(3000, function () {
  console.log('HTTP server listening on port ' + 3000)
})

Start it with:

node server.js

Then navigate to http://localhost:3000/connect, you can use your browser for now.

authorize.html

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
  <title>Client Side Implicit OAuth Flow</title>
  <script type="text/javascript" charset="utf-8">
    var config = {
      client_id: '[CLIENT_ID]',
      redirect_uri: '[REDIRECT_URL]',
      username: '[USERNAME]',
      password: '[PASSWORD]'
    }

    var authorize_url = 'https://www.instagram.com/oauth/authorize/?' +
      'client_id=' + config.client_id + '&' +
      'redirect_uri=' + config.redirect_uri + '&' +
      'response_type=token'

    document.addEventListener('DOMContentLoaded', function (e) {
      var iframe = document.querySelector('iframe')
      iframe.setAttribute('src', authorize_url)
      iframe.onload = function (e) {
        var doc = this.contentWindow.document
        // login
        if (doc.querySelector('[name=username]')) {
          doc.querySelector('[name=username]').value = config.username
          doc.querySelector('[name=password]').value = config.password
          doc.querySelector('[type=submit]').click()
        }
        // authorize
        else if (doc.querySelector('[value=Authorize]')) {
          doc.querySelector('[value=Authorize]').click()
        }
      }
    }, false)
  </script>
</head>
<body>
  <iframe src=""></iframe>
</body>
</html>

Once you hit that route a new process is spawned and the authorize.html is executed. Just keep in mind that NWjs requires some graphical libraries to be installed on your server, so it's not exactly a headless browser.

There the browser navigates to the authorization URL inside an iframe. Depending on whether you are logged in or already authorized the app different pages are loaded. This code just fills in your user name and password and clicks on a few links.

Once the OAuth flow is complete you get the access_token as hash in the URL. As you may know the browser doesn't send that part of the URL to the server, so in the /callback route the server returns another page called token.html which sole purpose is to extract the access token from the URL hash and return it as a querystring in the /token route.

token.html

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
  <title>Client Side Implicit OAuth Flow</title>
  <script type="text/javascript" charset="utf-8">
    var config = {
      callback_uri: 'http://localhost:3000/token'
    }

    var access_token = window.location.hash.replace('#access_token=', '')
    var url = config.callback_uri + '?access_token=' + access_token

    window.location.href = url
  </script>
</head>
<body>
</body>
</html>

After you run this example you'll see your access token in the command line:

$ node server.js 
HTTP server listening on port 3000
{ access_token: '1404767371.e5610d0.3381e9a2fd7340d8b90b729f407949d2' }
NW closed

You can download all files from here.



来源:https://stackoverflow.com/questions/33993650/working-with-basic-node-oauth-redirect-following

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!