passport-oauth accessing remote url - node.js

I try to implement an OAuth solution in nodejs. I used passport-oauth for generating the acccess tokens and refresh tokens which is working.
var passport = require('passport'),
OAuth = require('oauth').OAuth,
url = require('url'),
ArenaNet = require('passport-oauth').OAuth2Strategy,
config = require('../config'),
users = require('../../app/controllers/users.server.controller');
module.exports = function() {
passport.use('arenanet', new ArenaNet({
authorizationURL: config.arenanet.authorizationURL,
tokenURL: config.arenanet.tokenURL,
clientID: config.arenanet.clientID,
clientSecret: config.arenanet.clientSecret,
callbackURL: config.arenanet.callbackURL,
response_type: "code",
scope: "offline account"
},
function(accessToken, refreshToken, code, profile, done) {
console.log(accessToken);
console.log(refreshToken);
console.log(code);
done();
}));
};
This generates the following output:
69XXXXF-776D-4CXX-AXX7-29XXXXXX4DB5
5FXXXXXX-XXX67-E1XXX1-809D-XXXXXXXXXXXXXXXX-XX69-4XX6-XXF-4C6XXXXX08EB
{ access_token: 'XX0XXXXXF-77XXX-4XXXX-XXXA7-295XXXXXXB5',
token_type: 'Bearer',
scope: 'account' }
I am new to OAuth. What confuses me now is how to access a remote url with the tokens. What i have in mind is something like this:
oauth.get(
"https://api.guildwars2.com/v2/account",
accessToken,
function(err, body, response) {
console.log(body);
}
);
What obviously don't work. I saw several examples how i can access local sites with the token, but not how to request something from a remote url.
Any suggestion how i'm able to this with passport-oauth? Or do i need to use a different module for this action?
I hope you can help me here, would be cool!
Thank you all and best regards,
michael

Related

Post To Twitter on Behalf of Another User using Node.js, express, twit, and passport-twitter

Using the Twitter API, I'm trying to post a tweet on behalf of a Twitter user.
I'm using node and the passport-twitter and twit modules.
Some resources:
I followed this video tutorial NodeJS and ExpressJS: Using Twitter
authentication via Passport.
Sourcecode for the tutorial
here.
Passport-twitter documentation
twit documentation
I successfully authenticated with passport-twitter following the tutorial above.
I also successfully posted using twit on my twitter developer account.
However, I'm having trouble combining these two things; trying to post to twitter on behalf of another user. For that, I need to get the user's access token and access token secret. Then, I need to make a post request to the Twitter API with that information.
I'm not sure where to put the post request in the passport-twitter code. I tried putting it in the second route which is the URL to which Twitter redirects the user after they have signed in.
app.get('/twitter/login', passport.authenticate('twitter'))
app.get('/twitter/return', passport.authenticate('twitter', {
failureRedirect: '/'
}), function(req, res) {
//Post using twit
//grab access token and access token secret from the request query
const access_token = req.query.oauth_token;
const access_token_secret = req.query.oauth_verifier;
//set the configurations with the access token and access token secret that we just got
const config = {
consumer_key: <consumer key here>,
consumer_secret: <consumer secret here>,
access_token,
access_token_secret,
timeout_ms: 60*1000,
strictSSL: true
}
//pass in the configurations
var T = new Twit(config);
//post
T.post('statuses/update', { status: 'hello world!' }, function(err, data, response) {
if (err)console.log("oops, didn't tweet: ", err.message);
})
res.redirect('/');
})
But I got an error: Invalid or expired token.
I expected it to work because the authentication worked.
This is my first time using OAuth so perhaps I misunderstand how this all works.
Where am I supposed to put the post request?
UPDATE:
I tried posting to my dev account, using my dev account's access token and secret. It worked. Which lead me to believe there is something wrong with the access token and secret for the user.
I think I know partially what’s going.
I assumed that the property oauth_verifier found in the request query object was the access token secret.
const access_token_secret = req.query.oauth_verifier;
But now I don’t think oauth_verifier is the same as the access token secret. oauth_verifier has less characters than my dev account’s access token secret. So it seems that the datatypes are different.
But now I’m trying to figure out where the access token secret is? There are only two properties in the request query object (req.query);
oauth_token
oauth_verifier
Where’s the access token secret for the user?
I solved my issue. It was in the documentation for passport-twitter all along. Man, I spent days on this issue.
The strategy also requires a verify callback, which receives the access token and corresponding secret as arguments, as well as profile which contains the authenticated user's Twitter profile.
-from passport-twitter readMe
In the example in the docs, you can see token and tokenSecret in the params.
passport.use(new TwitterStrategy({
consumerKey: TWITTER_CONSUMER_KEY,
consumerSecret: TWITTER_CONSUMER_SECRET,
callbackURL: "http://127.0.0.1:3000/auth/twitter/callback"
},
function(token, tokenSecret, profile, cb) {
User.findOrCreate({ twitterId: profile.id }, function (err, user) {
return cb(err, user);
});
}
));
I read this and saw this before. But assumed this was the the consumer key and consumer secret. I didn't realize it was what I was looking for: the access token and access secret.
So your post to twit would go something like this:
passport.use(new Strategy({
consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
callbackURL: 'http://localhost:3000/twitter/return'
}, function(token, tokenSecret, profile, callback) {
const configs = createConfigs(token, tokenSecret);
// Post to twitter
var Twit = require('twit')
var T = new Twit({
consumer_key: '...', //get this from developer.twitter.com where your app info is
consumer_secret: '...', //get this from developer.twitter.com where your app info is
access_token: token,
access_token_secret: tokenSecret,
timeout_ms: 60*1000, // optional HTTP request timeout to apply to all requests.
strictSSL: true, // optional - requires SSL certificates to be valid.
})
//
// tweet 'hello world!'
//
T.post('statuses/update', { status: 'hello world!' }, function(err,
data, response) {
console.log(data)
})
return callback(null, profile);
}));

access_token not present in the passport-github2 request

I have registered an OAuth App via my Github account. I am basically trying to authorize my node requests(by sending access_token as part of request cookies) so I can access few APIs on another server. Hence I am using the github-passport2 package. I have setup the github strategy etc. & it seems to be all according to the doc. The flow works well too.
My Issue
After logging into Github(authorized) & getting redirected back to my /auth/github/callback, I ideally should be authorized and should have an access_token in the req. But I don't have it! Because of this I am not able to authorize my future requests with an access_token.
Important to note is that, this access_token is automatically attached when the request is initiated from a browser/client(using withCredentials: true parameter). The same access_token via node doesn't seem to be retrievable.
passport.use(new GitHubStrategy({
clientID: GITHUB_CLIENT_ID,
clientSecret: GITHUB_CLIENT_SECRET,
callbackURL: "http://localhost:8080/auth/github/callback",
},
function(accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
return done(null, profile);
});
}
));
app.get('/auth/github', passport.authenticate('github', { scope: [ 'user:email' ] }), function(req, res){
// The request will be redirected to GitHub for authentication, so this
// function will not be called.
});
app.get('/auth/github/callback', passport.authenticate('github', { failureRedirect: '/login' }), function(req, res) {
console.log(req); // <- This ideally should have the access_token? but doesn't
});
I have struggling for days on this. Any help is much appreciated.

Get google OAuth 2.0 refresh token using PassPortJS and Node.jS

I am having trouble getting a refresh token from Google using Passport JS. I have been removing access in my account permissions to make sure it is a first time login. I keep getting "undefined" for the token. Here is the code I have at the moment.
Passport.use(new GoogleStrategy({
clientID: "xxxxx.apps.googleusercontent.com",
clientSecret: "xxxxx",
callbackURL: `https://localhost:${port}/auth/google/callback`,
accessType: 'offline',
passReqToCallback: true
},
function(req,accessToken, refreshToken, profile, done) {
var tokens = {
access_token: accessToken,
refresh_token: refreshToken
}
console.log(tokens)
oauth2Client.setCredentials(tokens);
done(err = false, user = true)
}));
If anyone has experience working OAuth into their web apps that could lend a hand it would be greatly appreciated
The answer was in requesting it during the innitail route and creating the consent prompt each time.
app.get('/auth/google', passport.authenticate('google',{accessType: 'offline', prompt: 'consent', scope: ['openid profile email https://www.googleapis.com/auth/drive']}))
To get the refresh token using passportJS in NodeJS you simply have to add 2 more access fields ( accessType: 'offline', prompt: 'consent' ) in the router section.
ex.router.get('/auth/google', passport.authenticate('google', {
scope: ['profile'],
accessType: 'offline',
prompt: 'consent'
}));
After that you will receive a refresh token.
Note: If your application is not verified by the Google then it will so you warning.
Simply click on the advance button below and you are ready to go.

Node React Google Login

I have been learning react and node together and have been trying to implement using google auth. I believe I have the front end side working as I can get an access token back but I can't seem to complete the authentication with the node side of it. Here is my React code.
export default class GoogleLoginComponent extends Component {
responseGoogle(response){
var id_token = response.getAuthResponse().id_token;
var googlePlus = '101603157010265563225'
console.log({accessToken: id_token});
//axios.get('oauth',id_token)
}
render(){
return(
<GoogleLogin
clientId="115435392551-qamvp0loln91e4d2uoat8pnki4f705o6.apps.googleusercontent.com"
buttonText="Login"
onSuccess={this.responseGoogle.bind(this)}
onFailure={this.responseGoogle.bind(this)}
/>
)
}
}
This will print out the id_token successfully for me. My issue I believe at least(but what do I know) is on the server side. In google I set up oauth as the callback address. Will Google make the get call to oauth or do I have to do it? When I try and do it myself I get a whole mess of errors. Here is the server side code.
var GoogleStrategy = require( 'passport-google-oauth2' ).Strategy;
passport.use(new GoogleStrategy({
clientID: "115435392551-qamvp0loln91e4d2uoat8pnki4f705o6.apps.googleusercontent.com",
clientSecret: "_9tCI3_e-oKFwz1kFkxvRKMM",
callbackURL: "http://localhost:3000/oauth",
passReqToCallback : true
},
function(accessToken, refreshToken, profile, done) {
User.findOrCreate({ googleId: profile.id }, function (err, user) {
return done(err, user);
});
}
));
app.get( '/oauth',
passport.authenticate( 'google', {
successRedirect: 'success.html',
failureRedirect: 'fail.html'
})
);
Any ideas would be greatly appreciated.

Using PassportJS google authentication with the nodejs google api library

I'm currently looking at implementing a google api, using the nodejs client:
https://github.com/google/google-api-nodejs-client/
I'm trying to use passport in order to authenticate, which seems to be working#
passport.use(new GoogleStrategy({
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: "http://localhost:3000/auth/google/callback"
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function () {
var user = {
id: profile.id,
email: profile.email,
firstName: profile.given_name,
lastName: profile.family_name,
accessToken: accessToken
};
return done(null, user);
});
}
));
In my google auth callback:
app.get('/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
function(req, res) {
//do something here with the google api
});
I can get hold of req.user, and this has the accessToken
However, the docs for the Google api nodejs client aren't clear on how to use an accessToken.
The example included shows the OAauth2Client retrieving a token, but I guess that part has already been covered using Passport?
I'm not familiar with google-api-nodejs-client, but this is in their documentation:
oauth2Client.credentials = {
access_token: 'ACCESS TOKEN HERE',
refresh_token: 'REFRESH TOKEN HERE'
};
client
.plus.people.get({ userId: 'me' })
.withAuthClient(oauth2Client)
.execute(callback);
I assume you can just set the credentials to those provided by Passport, and things will work fine.
Honestly, though, I find these API wrappers really contrived, and recommend just using request. That way you can access any API service from any provider using a familiar module.

Resources