I am working on twitter oauth through chrome extension. I need to get oauth_token to authenticate the user. I am referring to https://developer.twitter.com/en/docs/tutorials/authenticating-with-twitter-api-for-enterprise/oauth1-0a-and-user-access-tokens. Can you guide me to send post request for my oauth token in javascript ?
You can refer to the above link for steps but I need to implement my post request in background.js instead to sending it in postman. I need my ext to create new request for each login, which for create different oauth token for each session.
I want to create a post request with following requirements:
URL-'https://api.twitter.com/oauth/request_token'
query- 'oauth_callback':'oob'
auth- we want to provide consumer key and consumer secret here
headers- 'Content-Type':'application/json'
This is a screenshot of postman. On implementing this, the post request returns oauth token and secret.
Please help me out on this.
import oauth from 'oauth';
const oauthCallback = process.env.FRONTEND_URL;
const CONSUMER_KEY = process.env.CONSUMER_KEY;
const CONSUMER_SECRET = process.env.CONSUMER_SECRET;
const _oauth = new oauth.OAuth(
'https://api.twitter.com/oauth/request_token',
'https://api.twitter.com/oauth/access_token',
CONSUMER_KEY, // consumer key
CONSUMER_SECRET, // consumer secret
'1.0',
oauthCallback,
'HMAC-SHA1',
);
export const getOAuthRequestToken = () => {
return new Promise((resolve, reject) => {
_oauth.getOAuthRequestToken((error, oauth_token, oauth_token_secret,
results) => {
if (error) {
reject(error);
} else {
console.log({ oauth_token, oauth_token_secret, results });
resolve({ oauth_token, oauth_token_secret, results });
}
});
});
};
Try this method in your backend to get the OAuth token and secret. It helped in my case, maybe it can work for you as well.
Use this to install oauth lib
npm i oauth
Refer for more info:
https://javascript.works-hub.com/learn/building-with-twitter-authentication-35ad6
Related
I currently have an app with the following structure: Angular front-end, Node.js server.
We have implemented Google Cloud's Identity Providers to sign in using Google and/or Microsoft.
Google Sign-in and access the Google Cloud Admin SDK working perfectly, however trying to access Microsoft Graph is giving the following error:
UnhandledPromiseRejectionWarning: Error: Required claim nbf not present in token
According to Firebase documentation you can use the access token recieved from the Signin to access Graph:
Firebase documentation screenshot
On successful completion, the OAuth access token associated with the provider can be retrieved from the firebase.auth.UserCredential object returned. Using the OAuth access token, you can call the Microsoft Graph API. For example, to get the basic profile information, the following REST API can be called:
curl -i -H "Authorization: Bearer ACCESS_TOKEN" https://graph.microsoft.com/v1.0/me
When running the above in url I get the same error:
{"error":{"code":"InvalidAuthenticationToken","message":"Required claim nbf not present in token","innerError":{"date":"2022-05-26T12:51:11","request-id":"##########","client-request-id":"##########"}}}
I'm using the signInWithPopup in my authentication service (authentication.service.ts):
await signInWithPopup(this.auth, provider)
.then((result) => {
const credential = OAuthProvider.credentialFromResult(result);
const accessToken = credential.accessToken;
const idToken = credential.idToken;
this.setCurrentUser(result.user);
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
const email = error.email;
const credential = OAuthProvider.credentialFromError(error);
console.log(error);
});
I send the accessToken to my server (app.ts):
app.get(
'/api/microsoft-get-organisation',
async (req: express.Request, res: express.Response) => {
//https://graph.microsoft.com/v1.0/organization
const organisation = await ms.getOrganisation(req.headers, '/organization');
res.send(JSON.stringify(organisation));
}
);
export const getOrganisation = async (headers: any, graphEndpoint: string) => {
const client = await getAuthenticatedClient(headers);
return await client.api(graphEndpoint).get();
};
async function getAuthenticatedClient(headers: any) {
const client = await graph.Client.init({
authProvider: (done: any) => {
done(null, headers.authorization.split(' ')[1]);
},
});
return client;
}
When verifying the token I can see that there is no nbf claim:
token screen shot
Any advice on what I have done wrong so that I can access Microsoft Graph?
I'm following this tutorial:
https://learn.microsoft.com/en-us/learn/modules/msteams-sso/7-exercise-bots-sso
https://github.com/OfficeDev/TrainingContent/tree/master/Teams/80%20Using%20Single%20Sign-On%20with%20Microsoft%20Teams/Demos/02-learn-msteams-sso-bot
https://youtu.be/cmI06T2JLEg
https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/javascript_nodejs/24.bot-authentication-msgraph
The bot worked as expected. But I would like not to use the dialog framework. I'm having trouble adapting the model.
In the personal scope I reply to a message with an oauth card:
const oauthCard = await CardFactory.oauthCard(SsoConnectionName, undefined, undefined, undefined, {
id: 'random65jHf9276hDy47',
uri: `api://botid-${MicrosoftAppId}`
})
await context.sendActivity(MessageFactory.attachment(oauthCard))
so i get the token on the handler
handleTeamsSigninTokenExchange(context, query) {
if (context?.activity?.name === tokenExchangeOperationName) {
console.dir(context?.activity?.value)
token = context?.activity?.value?.token
}
}
What am I supposed to do with this token? I get the Invalid x5t claim error when I try to use microsoft client like this:
msGraphClient = microsoft.Client.init({
debugLogging: true,
authProvider: done => {
done(null, token)
}
})
// on message 'whoiam'
const me = await msGraphClient.api("me").get()
Is this the correct token? How do I initialize the Microsoft Graph client with this token?
My repo sample: https://github.com/itacirgabral/teamsbotSSOdemo/blob/nodialog/nodialogs.js
You can use below code snippet for initializing the Graph Client:
// Get an Authenticated Microsoft Graph client using the token issued to the user.
this.graphClient = Client.init({
authProvider: (done) => {
done(null, this._token); // First parameter takes an error if you can't get an access token.
}
});
Refence sample link:
https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/app-sso/nodejs/server/models/simpleGraphClient.js
https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/app-sso/nodejs/server/api/appController.js
I want to display the tweets that users see in their Twitter home timeline. Concept here is
First, let the user login with "login with Twitter" functionality and get an OAuth token.
Then request Twitter API with those keys and get tweets.
So far I have achieved to get the timeline of my own developer account.
Here is the Nodejs code to get those tweets.
const {access_token, access_token_secret} = request.body;
const T = new Twit({
consumer_key: "xxxxxxxxxxxxxxxxxxxxx",
consumer_secret: "xxxxxxxxxxxxxxxxxx",
access_token,
access_token_secret,
});
const tweets = await this.T.get('statuses/home_timeline', { count: 40 });
Here is the API request from the frontend
export const loadPersonalTweets = (
access_token,
access_token_secret
) => () => {
axios
.post(`http://localhost:8000/tweet/homeTimeline`, {
access_token,
access_token_secret,
})
.then(
(res) => {
console.log(res) // supposed to get user's personal timeline
},
(err) => {
console.log(err);
}
);
};
I have retrieved consumer_key and consumer_secret from my developer account and I receive access_token and access_token_secret from the frontend app after the user authorizes it.
But it doesn't return what the other user sees in their timeline rather it returns the timeline of my developer account.
Can anyone redirect me to the correct way?
Edit: This is the token I get after users authorize the frontend app
I'm attempting to use Auth0 to issue JWT tokens for accessing my API (so that Auth0 handles all the OAuth and security concerns, etc., and my API just needs to check the token). When I try to test the Authorization Code flow for clients to receive an access token (using Node + Express), the following happens:
The authorization code request works fine, and the client is redirected back to my redirect_uri with the code appended to the query. All good.
The token request then always fails. If I include the audience parameter, the request returns an access_denied error with the following details: Service not found: {the audience parameter}, regardless of what value I set for the audience parameter.
If I don't include the audience parameter, I get a server_error with the message Service not found: https://oauth.auth0.com/userinfo.
I've checked every Auth0 setting and read every documentation page thoroughly, and so far nothing has worked. I've also tested the Authorization Code flow in Auth0's API debugger, and it worked fine. My test follows exactly the same parameters, and yet still receives an error requesting the token. I'm testing on localhost. The client credentials and implicit flows are working fine.
Here is a test endpoint I created which retrieves the authorization code from Auth0:
const qs = require('querystring');
const getCode = (req, res) => {
const params = {
audience, // the value of the API Audience setting for the client
client_id, // the client ID
redirect_uri, // the redirect_uri, which is also listed in the Allowed Callback URLs field
response_type: `code`,
scope: `offline_access open` // ask to return ID token and refresh token,
state: `12345`,
};
const authDomain = `mydomain.auth0.com/oauth`;
res.redirect(`${authDomain}/oauth/authorize?${qs.stringify(params)}`);
};
The redirect_uri then redirects to the following endpoint, where I make the request for the access token:
const https = require('https');
const callback = (req, res) => {
const body = {
client_id,
client_secret,
code: req.query.code,
grant_type: `authorization_code`,
redirect_uri, // same value as provided during the code request
};
const opts = {
headers: { 'Content-Type': `application/json` },
hostname: `mydomain.auth0.com`,
method: `POST`,
path: `/oauth/token`,
};
const request = https.request(opts, response => {
let data = ``;
response.on(`data`, chunk => { data += chunk; });
response.on(`error`, res.send(err.message));
response.on(`end`, () => res.json(JSON.parse(data))); // this executes, but displays the error returned from Auth0
});
request.on(`error`, err => res.send(err.message));
request.end(JSON.stringify(body), `utf8`);
};
Any suggestions as to what I might be doing wrong?
The issue was that I was calling the incorrect URL at Auth0. I mistakenly thought that both the authorization and token endpoints began with /oauth, when in fact the authorization endpoint is just /authorize, while the token endpoint is /oauth/authorize. Correcting the URLs in my code fixed the problem.
My solution was the identifier of the api was not found. If it is not exact it won't find it. I had an extra backslash on my 'audience' where the identifier didnt have one. pretty easy mistake but the error is not very clear in Auth0.
In my case, I was using auth0 react hooks. So the example code looked like this:
const getUserMetadata = async () => {
const domain = process.env.REACT_APP_AUTH0_DOMAIN
try {
const accessToken = await getAccessTokenSilently({
audience: `https://${domain}/api/v2/`,
scope: 'read:current_user',
})
console.log('accessToken', accessToken)
localStorage.setItem('access_token', accessToken)
setUserAuthenticated(true)
} catch (e) {
console.log('error in getting access token', e.message)
}
}
My solution to this was using by default Auth0 Audience value in audience field
const getUserMetadata = async () => {
const auth0audience = process.env.REACT_APP_AUTH0_AUDIENCE
try {
const accessToken = await getAccessTokenSilently({
audience: auth0audience,
scope: 'read:current_user',
})
console.log('accessToken', accessToken)
localStorage.setItem('access_token', accessToken)
setUserAuthenticated(true)
} catch (e) {
console.log('error in getting access token', e.message)
}
}
Because its stated in auth0 docs of configuring custom domains that, you need to use by default API audience
Source - https://auth0.com/docs/brand-and-customize/custom-domains/configure-features-to-use-custom-domains
I'm trying to create JWT tokens in node.js for use with the REST api in firebase, but when I try to use them, I get the error "Error: Invalid claim 'kid' in auth header."
This is my code
http.createServer(function (req, res) {
var payload = {
uid: "bruh"
};
var token = jwt.sign(payload, sact["private_key"], {
algorithm: 'RS256',
issuer: sact["client_email"],
subject: sact["client_email"],
audience: 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',
expiresIn: '3600s',
jwtid: sact["private_key_id"],
header: {
"kid": sact["private_key_id"]
}
});
res.writeHead(200);
res.end("It worked. (" + token + ")");
}).listen(port);
These are my requires
var http = require('http');
var jwt = require('jsonwebtoken');
Please use returnSecureToken: true, with correct Spellings
I hope it will solve the problem of Invalid claim 'kid' in the auth header.
This is an issue because you're generating a Firebase ID token, not an access token for the Firebase REST API.
To generate a REST API token I would use the legacy Firebase Token Generator library which still works perfectly well (but only generates REST tokens, not general purpose access tokens).
Note that your Firebase Database secret is now located under the gear icon in the top left of the console.
So I had this error and I've fixed it. Now here is the solution:
You'll need to retrieve the ID-token using an additional function. Here is the function you can use:
firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
// Send token to your backend via HTTPS
// ...
}).catch(function(error) {
// Handle error
});
I implemented it somewhat like this:
//google OAuth login handler
const googleLoginHandler = () => {
const provider = new firebase.auth.GoogleAuthProvider();
firebase.auth()
.signInWithPopup(provider)
.then((result) => {
/** #type {firebase.auth.OAuthCredential} */
setgoogleAuthStatus(true)
// The signed-in user info.
const userId = result.user.uid;
const displayName = result.user.displayName;
const email = result.user.email;
//This is the function for getting the ID-Token
firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then((idToken) => {
// Send token to your backend via HTTPS
console.log(idToken)
}).catch((error) => {
// Handle error
console.log(error.message)
alert(error.message)
});
console.log(result)
}).catch((error) => {
console.log(error)
// Handle Errors here.
alert(error.message)
})
}
The id token you get by this method can be used to access the firebase real-time database and other firebase services.
check out these links for more details:
https://firebase.google.com/docs/auth/admin/verify-id-tokens#retrieve_id_tokens_on_clients
https://firebase.google.com/docs/database/rest/auth#firebase_id_tokens