Oauth2/invalidate_token not working with 'Sorry, that page does not exist' code 34 Error

oauth

#1

This is my last thread I posted 25 days ago with my code and what I got:

got no help from it.

This time, I’m trying to revoke with the twitter npm module:

client = new Twitter({
    consumer_key: 'KEY',
    consumer_secret: 'SECRET',
    bearer_token: 'BEARER_TOKEN'
})

function revoke() {
    client.post("oauth2/invalidate_token", {access_token}, (err, tweets, response) => {
        if(err) {
            console.log(err)
            throw err
        }

        console.log(tweets)
        console.log(response)
    })
}

revoke()

I did test that it works with the trends/place.json but it won’t invalidate the token and gives me:

[ { message: 'Sorry, that page does not exist', code: 34 } ]

I did test that oauth/invalidate_token works with this twitter module, however.


Unable to invalidate Bearer token
AccessToken/AccessTokenSecret
#2

Hi @chulman444,

I think that’s because of this:

While POST oauth/invalidate_token allows a API version number in its request URI (=> /1.1/), POST oauth2/invalidate_token doesn’t require a version naumber. Does this make sense to you?

Best,
Shohei


#3

@jrsyo, thank you for the reference to the source code of the module. So I must had been sending a request to the https://api.twitter.com/1.1/trends/place.json when I should’ve sent a request to https://api.twitter.com/trends/place.json. I was able to make the request with axios easily.

However my problem with oauth2/invalidate_token end point hasn’t still resolved:

const axios = require('axios')
const qs = require('querystring')

let token_url = "https://api.twitter.com/oauth2/token";
let revoke_url = "https://api.twitter.com/oauth2/invalidate_token"
let auth = {
    username: "CONSUMER_API_KEY",
    password: "CONSUMER_API_SECRET"
}

async function main() {
    // First, obtain the bearer token
    let response = await axios.post(token_url, "grant_type=client_credentials", { auth })

    // Bearer token. Can be used when sending an API request with `Authorization: Bearer ....`    let access_token = response.data["access_token"]

    let api_response = await axios.get("https://api.twitter.com/1.1/trends/place.json?id=1", {        headers: {
            Authorization: `bearer ${access_token}`
        }
    })

    console.log("API request with bearer token:")
    console.log(Object.keys(api_response.data[0]))

    let json_data = {
        "access_token": access_token
    }
    let data = qs.stringify(json_data)

    // However when making an invliadation request, use the same authroziation as when obtaining the bearer token.
    axios.post(revoke_url, data, { auth })
    .then( response => {
        console.log("REVOKE SUCCESS")
        console.log(response)
    })
    .catch( e=> {
        console.log("Failed to revoke")
        // console.log(e)
        console.log(e.request._header) // Header
    })
}

main()

The header it produces:

POST /oauth2/invalidate_token HTTP/1.1
Accept: application/json, text/plain, */*
Content-Type: application/x-www-form-urlencoded
User-Agent: axios/0.18.0
Content-Length: 127
Host: api.twitter.com
Authorization: Basic VGZLS0xPMzJw...Q1MDdIeg==
Connection: close

I think it does send the access_token properly because it works with the trends/place.json, and when I use the json_data or no data, it throws:

message: 'Missing required parameter: access_token',

I referred to the following Twitter documentation:

and my demo code seems to be following it without any error.

I really can’t get my around this problem. Please help.

Thank you for your time,
Young


#4

@chulman444

I’m thinking one possible problem is because of doing this:

    let json_data = {
        "access_token": access_token
    }
    let data = qs.stringify(json_data)

I’m not sure why you wanted to use qs.stringify rather than just create a POST body data directly something like this:

let data = `access_token=${access_token}`

Because qs.stringify is designed for URI query parameter, it says:

When stringifying, qs by default URI encodes output.

As your access_token value usually has some special characters such as % so that it gets encoded after qs.stringify and it doesn’t match with your actual token.

Best,
Shohei


#5

@jrsyo

I’ve tried all three data types; stringify, the POST body data, the wrong POST json format, and even the form-data.

const axios = require('axios')
const qs = require('querystring')
const FormData = require('form-data')

let token_url = "https://api.twitter.com/oauth2/token";
let revoke_url = "https://api.twitter.com/oauth2/invalidate_token"
let auth = {
	username: "${username}",
	password: "${password}" 
}

async function main() {
    // First, obtain the bearer token
    let response = await axios.post(token_url, "grant_type=client_credentials", { auth })

    // Bearer token. Can be used when sending an API request with `Authorization: Bearer ....`
    let access_token = response.data["access_token"]

    let api_response

    try {
        api_response = await axios.get("https://api.twitter.com/1.1/trends/place.json?id=1", {
            headers: {
                Authorization: `bearer ${access_token}`
            }
        })
    }
    catch(e) {
        console.log("Maybe a problem with the access_token?")
        throw e
    }

    console.log("API request with bearer token:")
    console.log(Object.keys(api_response.data[0]))

    let json_data = {
        "access_token": access_token
    }
    let qs_data = qs.stringify(json_data)
    let string_data = `access_token=${access_token}`
    let form_data = new FormData()
    form_data.append("access_token", access_token)

    await invalidate(qs_data, "querystring") // code 348 error
    await invalidate(string_data, "POST data") // code 348 error 2
    await invalidate(json_data, "POST 'json data'") // code 170 error
    await invalidate(form_data, "POST form_data") // code 170 error 2
}

function invalidate(data, data_type) {
    return axios.post(revoke_url, data, { auth })
    .then( response => {
        console.log(`REVOKE SUCCESS with ${data_type}`)
        console.log(response)
    })
    .catch( e=> {
        console.log(`Failed to revoke with ${data_type}`)
        console.log(e.response.data)
        console.log(e.request._header)
    })
}

main()

The query_string, and the POST body data returns:

code: 348, message: 'Client application is not permitted to to invalidate this token.'

error, and the JSON and the form-data returns

{ code: 170,
       message: 'Missing required parameter: access_token',
       label: 'forbidden_missing_parameter' }

as expected?

In fact, the way you suggested was the method I tried with the original post I wrote in my very first question:

Please help me. I’m pasting the demo code hoping that my helper is running the same code as I do. I want to make sure if I’m actually missing things that I shouldn’t have. Or please provide me with the working code. I’m dying to know what the problem is.

I only installed the form-data and the axios module.

Thanks for your time,
Young


#6

@chulman444

OK, now it seems you finally got a clear error message as to why you’re unable to do so.

code: 348, message: ‘Client application is not permitted to to invalidate this token.’

because you’re using Application-only authentication. Please see the documentation carefully.

Application-only authentication doesn’t include any user contet. This means that you can only make requests to a Twitter API that doesn’t require an authenticated user.

Best,
Shohei


#8

@jrsyo

What I’m trying to do is to follow the “Invalidating a bearer token” section of the page you’ve linked me:

Should a bearer token become compromised or need to be invalidated for any reason, issue a call to POST oauth2 / invalidate_token.

And apparently, the hyper link this page provides is broken. The following API seems to be the corresponding one:

The API documentation and the page you linked shows the header used in the request:

POST /oauth2/invalidate_token HTTP/1.1
Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJn
                     NmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==
User-Agent: My Twitter App v1.0.23
Host: api.twitter.com
Accept: */*
Content-Length: 119
Content-Type: application/x-www-form-urlencoded

access_token=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

and the following is what I get from my demo code:

POST /oauth2/invalidate_token HTTP/1.1
Accept: application/json, text/plain, */*
Content-Type: application/x-www-form-urlencoded
User-Agent: axios/0.18.0
Content-Length: 127
Host: api.twitter.com
Authorization: Basic VGZLS0xPMzJw...Q1MDdIeg==
Connection: close

(Copy and pasted from the last reply)

Here is a confusion from your latest reply:

does that mean, I can’t invalidate the oauth2 token with the /oauth2/invalidate_token API?

So, is the documentation wrong? Because I’m trying to follow what the documentation says. I obtained the application-only OAuth2 token, and I’m trying to invalidate it following the ‘Invalidating a bearer token’ from the section at the bottom of the page you linked.

I’m trying to follow the documentations (Application-only authentication and oauth2/invalidate_token), I’ve compared the headers the documentations provides me and mine, I’ve provided my demo code. How do you invalidate the oauth2 token?

Please tell me what else to provide, and if possible, a working code to invalidate the oauth2 token.

Thanks,
Young


#10

Hi @chulman444 ,

Sorry, yes, my last answer was wrong. I confirmed that you’re doing nothing wrong with your sample code. It should work as we documented, but it looks like there were some internal changes on our side since last year which restrict this invalidation call and throw that error.

I will ping someone internally and hopefully get back to you soon. Thank you for your patience.

Best,
Shohei


#12

@jrsyo

Thank you! Will be waiting :smiley:

Young


#15

Ping