node-oauth2-server
node-oauth2-server copied to clipboard
Generate oAuth2 access_token without password for Facebook connection
Hi !
For a school project I need to secure my API with OAuth2. Very good module for !
I need to have login/register with Facebook and passport too.
Actually, when someone register new account with Facebook, we don’t have any password. Facebook send back the email and some other datas.
But, if someone need to login with Facebook, he can have access to any routes with OAuth2. Actually not. Because for generate OAuth2 access_token and so give access to all restricted routes, user need to post one password. But can’t possible with Facebook..
So my question : After register with Facebook, how can I give him an oauth2 access_token for navigate into all restricted routes ? Without password ?
You probably solved or gave up on it, but if it helps, this is how I did:
- Implement
client_credentials
grant - Create client for Facebook, and save it on database (use facebook's clientID and clientSecret). Don't forget to add
client_credentials
on it's grants - Create a user for Facebook with a
clientId
that points to Facebook's client - Use passport middleware before oauth's
token()
middleware, just like this:
router
.route(`athenticate/facebook`)
.post(
passport.authenticate('facebookToken', { session: false }),
this.oauthServer.token()
)
- Generate body that is accepted by oauth in passport strategy, here is my example:
passport.use(
'facebookToken',
new FacebookTokenStrategy(
{
clientID: <YOUR FACEBOOK CLIENT ID>,
clientSecret: <YOUR FACEBOOK CLIENT SECRET>,
passReqToCallback: true,
},
async (req, accessToken, refreshToken, profile, done) => {
try {
// body accepted by oauth
req.body.grant_type = 'client_credentials';
req.body.client_id =<YOUR FACEBOOK CLIENT ID>;
req.body.client_secret = <YOUR FACEBOOK CLIENT SECRET>;
req.headers['content-type'] = 'application/x-www-form-urlencoded';
// This was my way of saving a user, it does not interfere in token generation
const userService = new UserService();
const existingUser = await userService.findOne({
'facebook.id': profile.id,
});
if (existingUser) {
return done(null, existingUser);
}
const newUser = userService.registerUserFromSocial(
profile.emails[0].value,
'facebook',
profile.id
);
done(null, newUser);
} catch (error) {
done(error, false, error.message);
}
}
)
);
Leave the rest to token middleware and you're done, token should be generated! Hope it helps!