Difference between callbackUrl and function in passport-facebook - node.js

I'm trying to find out how Facebook authentication works when using passport-facebook with node/express.
I'm confused about the callbackURL and the function that follows below.
Can someone explain to me what the difference is between setting a callbackURL (is this where a successful login attempt end up? and the function(accessToken, ...) which also seems to be invoked after logging in.
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "http://localhost:3000/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
User.findOrCreate({ facebookId: profile.id }, function (err, user) {
return done(err, user);
});
}
));

callbackURL is a URL that facebook's web servers themselves will use at the end of the process. Facebook's servers will send a 301 redirect response causing the user's browser to navigate to this URL. So this is essentially a configuration option you are sending to facebook itself, and passport.js is handling the specifics of when and where to send it. When the whole oauth dance is done, the callback function is a way for passport to give control back to your code and say "hey, look it worked. Here's the goodies on the logged-in user", so you can do your findOrCreate. The details inside that function typically vary per-application whereas the oauth dance is always the same. So that's why passport uses a function callback there. It allows you a hook for application-specific or custom logic.

Related

Facebook login with app error Message: " Can't Load URL: The domain of this URL isn't included in the app's domains...."

I'm trying to implement Facebook login with Passport for my app hosted with an Herokuapp domain but I've been getting the above error message even after setting the values for app domain, website and OAUTH redirect URL.
Nothing I've seen here from previous answers seem to be working. Screenshots provided below
I was having this same issue, what finally worked for me was to make sure that the callbackURL exactly matched what was in Facebook's 'Valid OAuth Redirect URIs'.
For example, if you have https://example.com/auth/facebook/callback as a callback URI, then you need to have it listed exactly the same within your code -
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: 'https://example.com/auth/facebook/callback',
}, async (accessToken, refreshToken, profile, done) => {
...
}),
);
I had been using /auth/facebook/callback for my callbackURL, but it had to be the exact value that was given to Facebook in your apps settings.
Additionally, you may need to include the www version of your site in both your App Domains and your Valid OAuth Redirect URIs, as Facebook will throw an error if you try to go to https://www.example.com when you have only included https://example.com.
I have just fixed my issue. I receive the same error message when trying connect Facebook login with passport lib. My solution is to use full callback url instead. The code is below:
const FacebookStrategy = require('passport-facebook').Strategy
passport.use(
new FacebookStrategy({
clientID: process.env.FACEBOOK_ID,
clientSecret: process.env.FACEBOOK_SECRET,
callbackURL: 'https://your_domain.com/facebook/callback'
},
function(accessToken, refreshToken, profile, done) {
done(null, {profile: profile})
}
))
Hoping this is useful for you

Integrating of Google Login API in nodejs app

Currently I am working on making an e-commerce site using nodejs and mongodb. I want to integrate Google's API on the signup and login pages. Do the experts have any idea about this?
Use the GoogleStrategy of passport.js library.
example:
const passport = require('passport');
const { OAuthStrategy: { GoogleStrategy } } = require('passport-google-oauth');
passport.use(new GoogleStrategy({
consumerKey: GOOGLE_CONSUMER_KEY,
consumerSecret: GOOGLE_CONSUMER_SECRET,
callbackURL: "http://www.example.com/auth/google/callback"
},
(token, tokenSecret, profile, done) => {
User.findOrCreate({ googleId: profile.id }, function (err, user) {
return done(err, user);
});
}
));
read docs for more details http://www.passportjs.org/docs/google/
Try the following link, though It's already been mentioned in the comments below your question.
https://cloud.google.com/nodejs/getting-started/authenticate-users
It's the official google cloud platform documentation on how to get started authenticating users on node js. I hope it helps.
Creating a Google login will require you to work around with Google Developer Console.
Creating a project in Google Developer Console.
Creating OAuth Credentials, setting up Origin URI, and Redirect URLs.
I hope this link https://infantcoder.blogspot.com/2020/06/google-login-for-nodejs.html will help you create google login for your page.

Google oauth & apis how to do it

I can't find any documentation on using google oauth and google apis which I understand. At the moment, I am doing this, but it is not a complete guide: https://developers.google.com/identity/sign-in/web/server-side-flow
What I am trying to do:
I have a node based app, with a simple JS frontend.
It needs a google login.
When a user logs in, it creates a username for them on my server.
It stores some google token somehow under this user on my server.
Somehow give a service level access to my backend.
This backend can then make changes and read calendar info whenever needed, without user interaction.
At the moment I have a google login which returns an auth code like this: localhost:8000/?code=123. I don't know what to do with that auth code. Documentation is only provided for Java and Python unfortunately.
The next thing is to get the auth tokens (somehow) then figure out how to give my service account access.
Anyone know how?
Have you had a look at PassportJS? It has a very solid implementation for Google
I have done something similar for Facebook and will paste it here in case it helps:
So firstly, I added the below into my node app:
var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;
Then, the below:
app.use(passport.initialize());
app.use(passport.session());
Then, the below:
passport.serializeUser(function(user, done){
done(null, user.id);
});
passport.deserializeUser(function(id, done){
userModel.findById(id, function(err, user){
done(err, user);
});
});
passport.use(new FacebookStrategy({
clientID: config.facebook.appID,
clientSecret: config.facebook.appSecret,
callbackURL: config.facebook.callbackURL,
profileFields: ['id', 'displayName', 'photos', 'emails', 'birthday', 'location', 'bio', 'likes.limit(100)']
},
function(accessToken, refreshToken, profile, done){
//Do whatever I want
}
)
);
I won't explain all this but - see if it helps you with your Google apps integration. Good luck!

Create vs Login when using Google oauth for access

I am currently trying to setup my server to allow users to login with google oauth 2.0.
I am using passport and passport-google-oauth.
Normal set up is something like:
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
passport.use(new GoogleStrategy({
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: "http://127.0.0.1:3000/auth/google/callback"
},
function(accessToken, refreshToken, profile, done) {
User.findOrCreate({ googleId: profile.id }, function (err, user) {
return done(err, user);
});
}
));
However what I really want is to still control access to my server after accounts are approved.
Meaning a user would first 'create' and account using google, then be able to signin once there account is approved.
I would really like there to be a signup route and login route:
app.get('/auth/google/signup',
passport.authenticate('google', { scope: ['profile', 'email'] }));
app.get('/auth/google',
passport.authenticate('google', { scope: 'https://www.googleapis.com/auth/plus.login' }));
app.get('/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/');
});
My problem is that when I get to the GoogleStrategy setup I don't really know which route they initially hit. IE if they hit the login route but had not created an account I do not want to create an account I want to warn them that they did not yet create an account. Had they hit the signup route and already had an account I would not want to create another account I would just tell them they already have an account.
Is there anyway in the GoogleStrategy that I can tell which route the user initially hit on my server?
In your user model create the "approved" field, with default False (Boolean)
And you can check this field on the GoogleStrategy to restrict the access.
If you want to apply this on all Strategies you can filter on the serialization method in passport.
Hope it helps.
You can pass a 'state' query parameter in your initial request that will be round-tripped back to your callback.
Documented here:
https://developers.google.com/identity/protocols/OAuth2WebServer
state
Any string Provides any state that might be useful to your
application upon receipt of the response. The Google Authorization
Server roundtrips this parameter, so your application receives the
same value it sent. To mitigate against cross-site request forgery
(CSRF), it is strongly recommended to include an anti-forgery token in
the state, and confirm it in the response. See OpenID Connect for an
example of how to do this.

Best way to access the bearer token in mean/passportjs

Hey I am trying to work out where the bearer token is in a mean.io project.
I am using the default project which has Oauth enabled by default (have put the api keys in) and I can successfully log in.
How is passport storing the bearer token so I can authenticate my API calls? What is the best way to access it?
The token that is returned by the OAuth authentication is discarded by MEAN. See https://github.com/linnovate/mean/blob/v0.4.4/packages/users/passport.js:
passport.use(new FacebookStrategy({
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.facebook.callbackURL
},
function(accessToken, refreshToken, profile, done) {
// accessToken and refreshToken not used, not stored.
});
}
));
You could provide your own strategies to override this behavior, or try to raise the issue with MEAN. I see you already made a ticket. I'm afraid this may be a security consideration on their part, as there is no risk of losing the tokens if they are not stored.

Resources