Using PassportJS google authentication with the nodejs google api library - node.js

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.

Related

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.

Handling authentication in Nodejs with passport-facebook-token, request coming from frontend Facebook SDK

I am working on a Unity App. For login, there are two methods, one using Email and another using Facebook. In case of login separately, I do not have any problem. Registration and Login with Email works perfectly. And Login with Facebook works perfectly as well. Here's the workflow, I created just to make you clear.
tl;dr [read update]
There's another schema for account, which is used for login.
var Account = new Schema({
email: String,
password: String,
facebookId: String
});
Things to know about the backend API.
Passport is used for Authentication
Successful login returns email and token to the client through API.
On client, token is most to play game and use the overall features.
As I said, I have already covered the part when if a client registers and login using email, then client can use the app. But my confusion is handling the logins with Facebook. Facebook SDK is already integrated with the Unity App, and Login is success.
Now, how can I use the Facebook login information that is generated by the Facebook SDK onto my back end, so that I can authorize the user throughout the system, as done in email login.
Going through other questions in SO and Google, I came across passport-facebook-token, I also tried using the plugin but could not came up with the logic and flow for handling the data from SDK into the Nodejs API. Can someone me help understand how it is done?
Update 1: Using passport-facebook-token
Strategy on index.js
passport.use(new FacebookTokenStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET
}, function(accessToken, refreshToken, profile, done) {
Account.findOrCreate({facebookId: profile.id}, function (error, user) {
return done(error, user);
});
}
));
Controller API
api.post('/auth/facebook/token',
passport.authenticate('facebook-token'),
function (req, res) {
console.log(req.user);
// do something with req.user
res.sendStatus(req.user? 200 : 401);
}
);
Now, there is no error shown, but the data is not inserted into Account Schema, I have this findOrCreate() function in Model.
Account.statics.findOrCreate = function findOrCreate(profile, cb){
var userObj = new this();
this.findOne({facebookId : profile.id},function(err,result){
if(!result){
userObj.facebookId = profile.id;
//....
userObj.save(cb);
}else{
cb(err,result);
}
});
};
you can use facebook-passport for that, you can check the documentation here: https://github.com/jaredhanson/passport-facebook but basically, after you have already set up your developer account and got your keys from the developer site of facebook you can implement a FacebookStrategy object like following where you have to specify your credential and also a callback that in the documentation example is an http request to another resource of an express server where you can then save the data to mongo
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "http://localhost:3000/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, cb) {
User.findOrCreate({ facebookId: profile.id }, function (err, user) {
return cb(err, user);
});
}
));

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.

Refresh Yahoo OAuth 1.0 Access Token Using Passport

I have an Express app where I'm trying to refresh the Yahoo OAuth 1.0 access token before it expires after an hour so the user doesn't have to re-login. I'm using the https-passport-yahoo-oauth Passport strategy, which works for the initial OAuth.
There's a strategy (passport-oauth2-refresh) for refreshing the OAuth 2.0 token here, which I haven't been able to get to work (obvious reasons, I suppose).
Yahoo docs on refreshing the access token here => https://developer.yahoo.com/oauth/guide/oauth-refreshaccesstoken.html
This is my code for initial OAuth is below. How can I then exchange the expire or expiring token for a new one based off this?
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
var strategy = new YahooStrategy({
consumerKey: APP_KEY,
consumerSecret: APP_SECRET,
callbackURL: (process.env.APP_URL || require('./conf.js').APP_URL) + 'auth/yahoo/callback'
},
function(token, tokenSecret, profile, done) {
var data = profile._json;
var userObj = {
id: profile.id,
name: data.profile.nickname,
avatar: data.profile.image.imageUrl,
dateJoined: new Date().getTime(),
lastUpdated: new Date().getTime(),
lastVisit: new Date().getTime(),
accessToken: token,
tokenSecret: tokenSecret,
sessionHandle: profile.oauth_session_handle
};
return done(null, userObj);
}
);
passport.use(strategy);
I was thinking that I might be able to use Request, and roll my own token refresh, though I'm a little unsure with where to start there. Any help? Really appreciate any suggestions.
Yep, you can totally do that using request:
request.post('https://api.login.yahoo.com/oauth/v2/get_token', {
oauth: {
consumer_key:'...',
consumer_secret:'...',
token:'...',
token_secret:'...',
session_handle:'...'
}
}, function (err, res, body) {})
Alternatively you can use Purest as well. Note that you should store the session_handle when the user authorizes your app for the first time.

passport-oauth accessing remote url

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

Resources