How to get "Sign in with Twitter" working with NodeJS - javascript

Im trying to implement Sing In with Twitter working, however i keep getting the following error
Whoa there!
The request token for this page is invalid. It may have already been used, or expired because it is too old. Please go back to the site or application that sent you here and try again; it was probably just a mistake.
Here's my code, the what am I doing wrong?
// Server
var OAuth = require('oauth').OAuth;
var callbackUrl = null;
var oa = new OAuth(
'https://api.twitter.com/oauth/request_token',
'https://api.twitter.com/oauth/access_token',
CONSUMER_KEY,
CONSUMER_SECRET,
'1.0',
callbackUrl,
'HMAC-SHA1'
);
const promise = new Promise((resolve, reject) => {
oa.getOAuthRequestToken(function(error, token, secret, results) {
resolve({
token,
secret,
});
});
});
var oauth = await promise;
return { oauth };
// Client
window.open(`https://api.twitter.com/oauth/authenticate?oauth_token=${twitter.oauth.token})`);
I've also set the callback url to the same as what I have in the app details page, but no dice!
var callbackUrl = 'http://0.0.0.0:3001/settings/social/twitter/oauth';
Small note, not sure if it helps, but I've noticed the returned tokens are shorter than the examples I've seen online. Example:
Mine: EBhy3AAAAAAA94TPAAABajDwCww%
Twitter Site: NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0&

My client code had an extra ")"
window.open(`https://api.twitter.com/oauth/authenticate?oauth_token=${twitter.oauth.token})`);
should read
window.open(`https://api.twitter.com/oauth/authenticate?oauth_token=${twitter.oauth.token}`);

Related

I am getting " 'Request token missing': '' " error when trying to setup a client

I know that there is a very similar question like this one on StackOverflow, but i do not understand what the answer means, and because of that i am asking this question.
here's my code
const tokens = JSON.parse(fs.readFileSync("./tokens.json"));
const { accessToken, accessSecret, oauth_verifier } = tokens;
const client = new TwitterApi({
appKey: process.env.API_KEY,
appSecret: process.env.API_KEY_SECRET,
accessToken: accessToken,
accessSecret: accessSecret
});
const {client: Bot} = await client.login(oauth_verifier);
running this throws a 401 error with data saying Request token missing: ''.
i believe the problem lies in the oauth_verifier, as the code runs fine, and i have checked all my other credentials. I can also run a console.log() without running into errors if the last line in my code block above is commented.
The secret for getting this to work for me was not using .login().
Just instantiate the client using the details you got from the OAuth 1.0 auth flow. No need for .login()

Spotify PKCE code_verifier was incorrect

I was excited to hear that I can now use the Spotify web API without having a backend application via PKCE. Unfortunately, I seem to have some sort of misunderstanding and have been unable to get it to work.
I am likely making some minor mistake along the way, but I did it once to no avail and I wiped the slate clean and tried again but still without luck. From this I gather that I must be misunderstanding the documentation.
I will explain what I am doing and hopefully someone here can point out what I'm missing or doing wrong. I'm assuming I have a fundamental conceptual misunderstanding.
I first generate a cryptographically random string using an npm package called crypto-random-string. I store that in the browser's local storage before using js-sha256 to hash it and then using another npm package called base64url to encode it.
let verifier = cryptoRandomString({length: 50})
window.localStorage.setItem('verifier', verifier)
let params = {
client_id: '[MY CLIENT ID]',
response_type: 'code',
redirect_uri: 'http://localhost:3000/callback',
code_challenge_method: 'S256',
code_challenge: base64url(sha256(verifier))
}
let endpoint = new URL('https://accounts.spotify.com/authorize');
endpoint.search = new URLSearchParams(params);
window.location = endpoint.toString();
From here, I redirect to the /authorize endpoint with the proper url parameters. I have gotten this far successfully and then been redirected accordingly to my provided redirect_uri, where I grab the given code from the url parameters.
At this point, I try the fetch to the /api/token endpoint with the client_id, grant_type, the code I got from the url params, my redirect_uri, and the locally stored code_verifier.
let params = new URLSearchParams(window.location.search);
console.log(params.get('code'));
let newParams = {
client_id: '[MY CLIENT ID]',
grant_type: 'authorization_code',
code: params.get('code'),
redirect_uri: 'http://localhost:3000/callback',
code_verifier: window.localStorage.getItem('verifier')
}
let endpoint = new URL('https://accounts.spotify.com/api/token');
endpoint.search = new URLSearchParams(newParams);
fetch(endpoint.toString(), {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(data => data.json()).then(console.log)
At this point, after both of my attempts I received the error:
{ error: "invalid_grant", error_description: "code_verifier was incorrect" }
Is there anything that I am obviously doing wrong? The error leads me to believe I'm doing something wrong as far as the actual generation of the code_verifier, but I am at a loss to what that issue may be.
Someone on the Spotify forum pointed me to this answer. Not sure why exactly, but doing the encoding the following way does work:
async function sha256(plain) {
const encoder = new TextEncoder()
const data = encoder.encode(plain)
return window.crypto.subtle.digest('SHA-256', data)
}
function base64urlencode(a){
return btoa(String.fromCharCode.apply(null, new Uint8Array(a))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
}
const hashed = await sha256(verifyCode)
const codeChallenge = base64urlencode(hashed)
Previous answers and comments, in addition to OP, has documented most information needed so I will only add what helped me:
The verifier itself most be encoded as a Base64-URL.
Pseduo-code (as I myself code in C#):
verifier = Base64UrlEncode(GetRandomString(length: 50))
challenge = Base64UrlEncode(HashWithSha256(verifier))

Can someone ELI5 how to properly do offline Google oauth2 with node.js?

In the browser, I'm doing:
let { code } = await this.auth2.grantOfflineAccess();
I then save that code in my DB.
Then on the server (node.js), I'm doing:
const { tokens } = await oauth2Client.getToken(code)
oauth2Client.setCredentials(tokens)
let { data } = await googleCalendar.calendarList.list({
auth: oauth2Client
})
The first time, tokens has a refresh_token. I save that as well. When I run this once, it works fine. When I run it again, it says the token is invalid. Somehow, I have to use the refresh_token, to get a new token, but I don't know how. Can someone please explain like I'm 5?
Thanks
You have already had the refresh token.
You want to use the API with the access token refreshed by the refresh token.
You want to achieve this using googleapis with Node.js.
If my understanding is correct, how about this answer? I think that the reason of your issue is that the authorization code can be used only one time. So it is required to retrieve the access token using the refresh token. In this answer, the access token is retrieved by the refresh token.
Modified script:
const refreshToken = "###"; // Please set your refresh token.
if (!refreshToken) { // Please modify this if statement for your situation.
const { tokens } = await oauth2Client.getToken(code);
oauth2Client.setCredentials(tokens);
} else {
oauth2Client.credentials = { refresh_token: refreshToken };
}
let { data } = await googleCalendar.calendarList.list({
auth: oauth2Client
});
Note:
This modified script supposes that oauth2Client and googleCalendar are declared.
When the refresh token is used, the authorization code is not required.
Reference:
googleapis
If I misunderstood your question and this was not the result you want, I apologize.

403 error in calling DerivativeApi of Autodesk Forge

Autodesk Forge's DerivativeApi is not working with my client id and secret. Apis returns unauthorized error, { statusCode: 403, statusMessage: 'Unauthorized’ }.
But they works with the sample's client id/secret (from https://github.com/Autodesk-Forge/forge-api-nodejs-client/blob/master/samples/dmSample.js).
Is there any limitation for calling DerivativeApi (for translating) with free account? or should I do something?
Here is the sample code...
var ForgeSDK = require('forge-apis');
// TODO - insert your CLIENT_ID and CLIENT_SECRET
// Below id/secret from the sample are working, but mine is not.
var CLIENT_ID = 'wmizntnpzCJxPGF9lxsIiTZGbGO2cJqw',
CLIENT_SECRET = 'g5IPJwvhOHcrdbFy';
var derivativesApi = new ForgeSDK.DerivativesApi();
// Initialize the 2-legged oauth2 client
var oAuth2TwoLegged = new ForgeSDK.AuthClientTwoLegged(CLIENT_ID, CLIENT_SECRET,
['data:write', 'data:read', 'bucket:read', 'bucket:update', 'bucket:create'], true);
function defaultHandleError(err) {
console.error('\x1b[31m Error:', err, '\x1b[0m');
}
oAuth2TwoLegged.authenticate().then(function (credentials) {
console.log("**** Got Credentials", credentials);
derivativesApi.getFormats({}, oAuth2TwoLegged, oAuth2TwoLegged.getCredentials()).then(res => {
console.log(res);
}, defaultHandleError);
}, defaultHandleError);
Thanks
First, and extremely important, NEVER share your ID & Secret. If the above is your correct one, please create a new secret (to invalidate this).
Now the ID & Secret should work for any sample, just make sure you activated the APIs for it. On your app, select Model Derivative API on the screen, if not available, please review this article.
Finally, the code sample above is not actually calling Model Derivative. If so, note that files uploaded into one account are not accessible from other accounts, and URNs are unique.

Beatport API with node.js/js [general help needed]

Hello there everybody!
I am writing a simple multi-platform app for media tagging. It is written with the help of node-webkit and it is "almost" ready, the last and most important part is missing - beatport integration.
I have already acquired my self an API Key to work with (played with the docs), however I am heavily struggling to wrap my head around the OAuth protocol.
As far as I know I have to go thru the auth process, exchange consumer key and secret, login and receive the real access token - all of this can be done via the docs page and you end up with the access token and secret.
The question is how can I directly use the token and secret with something like this.
My awful attempt
var OAuth = require('mashape-oauth').OAuth;
var oa = new OAuth(method(url, oauth_token, oauth_token_secret, body, type, parameters, callback));
var url = "https://oauth-api.beatport.com/catalog/3/search/",
oauth_token = "MyToken", //obtained directly from the doc page
oauth_token_secret = "MyTokenSecret", //obtained directly from the doc page
parameters = "?query=Symphonica&facets=artistName%3ANicky+Romero",
body = "",
type = "",
callback = "";
console.log(oa);
Thank you very much any help will be appreciated. If anyone of you who help me, happen to be in prague I'll be very happy to buy you a beer.
(please take in consideration, that this is my first attempt to node/js I come from a php background I like to throw my self in the water even though I can't swim)
It is always about tinkering...
var sys = require('sys');
var OAuth = require('oauth').OAuth;
var oa = new OAuth("https://oauth-api.beatport.com/catalog/3/search/",
"https://oauth-api.beatport.com/catalog/3/search/",
"API KEY","API KEY SECRET",
"1.0A", undefined, "HMAC-SHA1");
var url = 'https://oauth-api.beatport.com/catalog/3/search/?query=Symphonica&facets=artistName:Nicky Romero',
access_token = "Access Token Obtained on doc pages",
access_token_secret = "Access Token Secret obtained on doc pages";
var request = oa.get(url, access_token, access_token_secret, function(error, data) {
if (error) {
console.log(error);
} else {
console.log(JSON.parse(data));
}
});
Changed the node module to this and tinkered with this example
I am going to buy myself a beer :-)

Categories

Resources