Y
Y
yaroslav19962019-11-11 17:52:40
Passwords
yaroslav1996, 2019-11-11 17:52:40

Authorization via node.js passport-facebook + jwtwebtoken in rest api application?

Sorry in advance if this question turns out to be stupid. At the moment, authorization is implemented in such a way that when an axios.post request is made from the client, the server sends a token, the token is stored in localstorage

app.post('/login/', async (req, res) => {
            try {
                const {email, password} = req.body;
                const errors = {};
                const user = await User.findOne({email});

                if (!user) {
                    errors.email = 'Account Not Found';
                    return res.status(404).send(errors);
                }

                const isMatch = await bcrypt.compare(password, user.password);

                if (isMatch) {
                    const payload = {
                        id: user._id,
                        email: user.email,
                    };

                    jwt.sign(payload, secret, {expiresIn: 3600}, (err, token) => {
                        if (err) {
                            res.status(500).send({
                                error: 'Error signing token',
                                raw: err,
                            });
                        }
                        res.send({
                            success: true,
                            token: `Bearer ${token}`,
                            email: user.email,
                        });
                    });



                } else {
                    errors.password = 'Password is incorrect';
                    res.status(400).json(errors);
                }

            } catch (error) {
                console.error(error);
            }

But I don’t quite understand how I can combine this with Facebook, how can I organize routes correctly if a person logged in with facebook, I need to generate a token and send it to the client, on the client I am going to write it to localstorage
module.exports = (app, passport) => {
    app.get('/login/facebook',
        passport.authenticate('facebook', {scope: 'email', session: false}));

// handle the callback after facebook has authenticated the user
    app.get('/login/facebook/callback',
        passport.authenticate('facebook', {
            successRedirect: 'http://localhost:3000/test',
            failureRedirect: '/',
            session: false
        })
    );
};

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
akyl-kb, 2019-11-12
@yaroslav1996

First you need to organize the structure more conveniently
Example as I have it organized:
- /models/User.js
- /passports/facebook.js
- /passports/google.js
- /passport.js
- /routes.js Passport.js
content

const User = require('./models/User')
const facebookStrategy = require('./passports/facebook')
const googleStrategy = require('./passports/google')

module.exports = function (passport) {
  passport.serializeUser(function (user, done) {
      return done(null, user.id)
  })

  passport.deserializeUser(async (id, done) => {
    try {
      const user = await User.findOne({ id })
      done(null, user)
    } catch (err) {
      done(err)
    }
  })

  passport.use(facebookStrategy())
  passport.use(googleStrategy())
}

facebookStrategy.js content:
const assert = require('assert')
const FacebookStrategy = require('passport-facebook').Strategy
const User = require('../models/User')

assert(process.env.FACEBOOK_APP_ID)
assert(process.env.FACEBOOK_APP_SECRET)
assert(process.env.APP_URL)

module.exports = () => {
  return new FacebookStrategy({
    clientID: process.env.FACEBOOK_APP_ID,
    clientSecret: process.env.FACEBOOK_APP_SECRET,
    callbackURL: `${process.env.APP_URL}/auth/facebook/callback`
  },
  async (accessToken, refreshToken, profile, done) => {
    try {
      const user = await User.findOrCreate({ facebook_id: profile.id }, {
        facebook_id: profile.id,
        name: profile.displayName,
        provider: 'facebook'
      })
      return done(null, user.toJSON())
    } catch (err) {
      return done(err)
    }
  })
}

routes.js
app.get('/auth/facebook', passport.authenticate('facebook'))
app.get('/auth/facebook/callback', passport.authenticate('facebook', { failureRedirect: '/login' }, (req, res) => {
  const user = req.user;
  const payload = {
      id: user._id,
      email: user.email,
  };

  jwt.sign(payload, secret, {expiresIn: 3600}, (err, token) => {
      if (err) {
          res.status(500).send({
              error: 'Error signing token',
              raw: err,
          });
      }
      // Отдаем html
      res.send(`
      <script>
        localStorage.setItem('token', '${`Bearer ${token}`}');
        localtion.href = '/'
      </script>
      `);
  });
})

in app.js
const passport = require('passport')
require('./passport')(passport)
app.use(passport.initialize())

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question