@yaroslav1996

Авторизация через node.js passport-facebook + jwtwebtoken в rest api приложении?

Извините заранее если этот вопрос, оказыватся глупым. На данный момент авторизация реализована таким образом, при axios.post запросе с клиента, сервер отправляет токен, токен сохраняется в 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);
            }


Но я не совсем, понимаю как мне это совместить с фейсбуком, как мне организовать правильно роуты если человек залогинился с facebook, мне нужно сформировать токен и его отправить на клиент, на клиенте я собираюсь записать его в 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
        })
    );
};
  • Вопрос задан
  • 1158 просмотров
Решения вопроса 1
@akyl-kb
Для начала нужно удобнее организовать структуру
Пример как у меня организовано:
- /models/User.js
- /passports/facebook.js
- /passports/google.js
- /passport.js
- /routes.js

Содержимое passport.js
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:
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>
      `);
  });
})


в app.js
const passport = require('passport')
require('./passport')(passport)
app.use(passport.initialize())
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы