2016-01-31

Ciclo completo para autenticarse por oauth2 en línea de comando

Hace un tiempito que estoy jugando con el API de blogger para hacer posts automaticamente. Lo que me parece más complicado es autenticarse vía oauth2 desde una aplicación de línea de comando. Por eso hice un módulo de sandro que lo hace por mi, pidiendo el código de autorización solo cuando es necesario

Se puede usar como módulo de sandro así:

define({
  accessToken: './accessToken'
},
function(m) {
  var accessToken = m.accessToken(
    'refresh_token_fname.txt', 
    {
      clientId: 'CLIENT ID HERE',
      clientSecret: 'CLIENT SECRET HERE'
    }
  )
  // Use accessToken here!
})

Abajo les dejo accessToken.js completo (cuidado, son 134 líneas de código):

define({
  javaPackages: "javaPackages",
  ary: "sandro/nadaMas/array",
  json: "sandro/nadaMas/json",
  object: "sandro/nadaMas/object"
}, function(m) {
 
  var URL = m.javaPackages.java.net.URL
  var String = m.javaPackages.java.lang.String
  var URLEncoder = m.javaPackages.java.net.URLEncoder
  var StandardCharsets = m.javaPackages.java.nio.charset.StandardCharsets
  var InputStreamReader = m.javaPackages.java.io.InputStreamReader
  var BufferedReader = m.javaPackages.java.io.BufferedReader
  var Scanner = m.javaPackages.java.util.Scanner
  var System = m.javaPackages.java.lang.System
  var File = java.io.File
  var FileOutputStream = java.io.FileOutputStream
  var OutputStreamWriter = java.io.OutputStreamWriter
  var out = System.out
  var in_ = new Scanner(System["in"])

  var paramBytes = function(p) {
    var s = new String( Object.keys(p).map(function(k) {
      return "" + URLEncoder.encode(k, "UTF-8") + "=" + URLEncoder.encode(p[k])
    }).join("&") )
    return s.getBytes(StandardCharsets.UTF_8)
  }
 
  var postJsonResult = function(url, params) {
    var parameters = paramBytes(params)
    var c = new URL(url).openConnection()
    try {
    c.requestMethod = "POST"
    c.doOutput = true
    c.fixedLengthStreamingMode = parameters.length
    c.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
    c.connect()
    c.outputStream.write(parameters)
  
    if (200 != c.responseCode) {
      return null
    }
    var response = ""
    var reader = new BufferedReader( new InputStreamReader( c.inputStream ) )
  
    while( true ) {
      var buff = reader.readLine()
      if (buff == null) {
        break
      }
      response += buff
    }
    return m.json.parse( "" + response )
    } finally {
      c.disconnect()
    }
  
  }
  var authCode2refreshToken = function(authCode, credentials) {
    var rv = postJsonResult(
      "https://www.googleapis.com/oauth2/v4/token", {
        code: authCode,
        redirect_uri: "urn:ietf:wg:oauth:2.0:oob",
        client_id: credentials.clientId,
        client_secret: credentials.clientSecret,
        grant_type: "authorization_code"
      }
    )
  
    return rv ? rv["refresh_token"] : null
  }
 
  var refreshAccessToken = function(refreshToken, credentials) {
    var rv = postJsonResult(
      "https://www.googleapis.com/oauth2/v4/token", {
        refresh_token: refreshToken,
        client_id: credentials.clientId,
        client_secret: credentials.clientSecret,
        grant_type: "refresh_token"
      }
    )
 
    return rv ? rv["access_token"] : null
  }
 
  var readFileLine = function(fname) {
    var sc = new Scanner(new File(fname))
    try {
      return sc.nextLine()
    } finally {
      sc.close()
    }
  }
 
  var writeFileLine = function(fname, line) {
    try {
      var w = new OutputStreamWriter( new FileOutputStream(fname) )
      line = "" + line
      w.write(line, 0, line.length)
    } finally {
      w.close()
    }
  }
 
  var obtainAccessToken = function(refreshTokenFname, credentials) {
    var accessToken = null
    var refreshToken = null
    try {
      refreshToken = readFileLine(refreshTokenFname)
    } catch (e) {
      // ignore
    }
  
    while (true) {
      if (refreshToken) {
        accessToken = refreshAccessToken(refreshToken, credentials)
      }
      if (accessToken) {
        return accessToken
      }
    
      var authorizationUrl =
        "https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/blogger&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&client_id=" +
        credentials.clientId
      out.println("Anda a este URL, completa la autorizacion y pega el codigo de autorizacion aca. Despues presiona ENTER")
      out.println(authorizationUrl)
      var authCode = in_.nextLine()
      refreshToken = authCode2refreshToken(authCode, credentials)
      writeFileLine(refreshTokenFname, refreshToken)
    }
  }
 
  return obtainAccessToken
})



Si quieren, es bastante fácil transliterarlo a código Java.

Espero que les sirva,
Aureliano.

No hay comentarios.: