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.