Messenger Chatbot - 使用Passport进行帐户关联和Facebook登录

时间:2017-03-19 01:29:30

标签: javascript node.js facebook passport.js passport-facebook

过去一周有些麻烦让这个链接正常工作。觉得我误解了流程中的某些东西。

我正在努力解决的问题是使用passport-facebook实施护照。我想将passport.authenticate包含在与帐户链接相同的路径中。目前只设法将两个进程分开并进行两次登录。希望合并它们。 从这里可以看出http://recordit.co/osdMl0MUCL

没有办法在链接路线内进行passport.authenticate吗?一直尝试没有成功。 试图在app.get中移动passport.authenticate('/ authorize但不知道如何处理const redirectURISuccess = $ {redirectURI}& authorization_code = $ {authCode}; res.redirect(redirectURISuccess);

我认为需要在app.get中进行此操作(/ auth / fb / callback'......但不确定如何。

这就是我目前的

'use strict';
require('dotenv').config();

const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');

const http = require('http');
const port = '3000';

const passport = require('passport');
const FacebookStrategy = require('passport-facebook').Strategy;
const fbConfig = require('./oauth');
const cookieParser = require('cookie-parser');
const session = require('express-session');
    // used to serialize the user for the session
    // Not using these yet
passport.serializeUser(function (user, done) {
  done(null, user.id);
});

passport.deserializeUser(function (obj, done) {
  done(null, obj);
});

const Botly = require('botly');
const botly = new Botly({
  accessToken: process.env.ACCESS_TOKEN,
  verifyToken: '123123321' // the verification token you provided when defining the webhook in facebook
});

const app = express();

// Listen on the account link event
botly.on('account_link', (sender, message, link) => {
    // Continue conversation
  console.log('CONFIRMED AUITH', link);
  botly.sendText({
    id: sender,
    text: (link.status === 'unlinked') ? 'sorry to see you go' : 'Welcome'
  });
  botly.sendButtons({
    id: sender,
    text: 'Please Login Again :-) This time for real',
    buttons: [ botly.createAccountLinkButton(`https://${process.env.LOGIN_DOMAIN}/auth/fb/?senderId=' + sender/`) ]
  });
});
botly.on('message', (senderId, message, data) => {
  const text = `echo: ${data.text}`;

  botly.sendText({
    id: senderId,
    text: text
  });
  botly.sendButtons({
    id: senderId,
    text: 'Please Login :)',
    buttons: [ botly.createAccountLinkButton(`https://${process.env.LOGIN_DOMAIN}/authorize/`), botly.createAccountUnLinkButton() ]
  });
});

app.use(bodyParser.json());
app.use('/', router);

app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({ secret: 'its_my_secret', resave: true, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use('/webhook', botly.router());
app.set('port', port);

/*
 * This path is used for account linking. The account linking call-to-action
 * (sendAccountLinking) is pointed to this URL.
 *
 */
app.get('/authorize', function (req, res) {
  // Passport setup
  passport.use('facebook', new FacebookStrategy({
    clientID: fbConfig.facebook.clientID,
    clientSecret: fbConfig.facebook.clientSecret,
    callbackURL: fbConfig.facebook.callbackURL,
    profileFields: [ 'id', 'displayName', 'email' ]

  },

  // facebook will send back the tokens and profile
  function (request, access_token, refresh_token, profile, done) {
    // asynchronous
    process.nextTick(function () {
      console.log('WATCH THIS: ', profile);
      return done(null, profile);
    });
  }));
  console.log('%%%%%%%% AccountLinking Testing');

  const accountLinkingToken = req.query.account_linking_token;
  const redirectURI = req.query.redirect_uri;

  console.log('%%%%%%%% /authorize called with accountLinkingToken %s, redirectURI %s', accountLinkingToken, redirectURI);

  // Authorization Code should be generated per user by the developer. This will
  // be passed to the Account Linking callback.
  const authCode = '1234567890';

  // Redirect users to this URI on successful login
  const redirectURISuccess = `${redirectURI}&authorization_code=${authCode}`;
  res.redirect(redirectURISuccess);
});

app.get('/auth/fb', (req, res, next) => {
  req.session.senderId = req.query.senderId;
  passport.authenticate('facebook', { scope: [ 'email' ] },
    {
      state: {
        senderId: req.query.senderId // senderId will be used after auth to reply to the user
      }
    })(req, res, next);
});

        // Redirection after login
app.get('/auth/fb/callback',
passport.authenticate('facebook', {
  successRedirect: `https://m.me/${process.env.app_name}`, // The webview I want to open if user logs in
  failureRedirect: '/somePage' // redirect to Messenger if failure
}));

const server = http.createServer(app);
server.listen(port);

1 个答案:

答案 0 :(得分:0)

我认为我解决了这个问题。可能不是最好的方法。我正在将帐户链接重定向URI传递给回调路由,并在需要时重定向中解析passport.authenticate。

'use strict';
require('dotenv').config();

const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
const LINKED = {};

const http = require('http');
const port = '3000';

const passport = require('passport');
const FacebookStrategy = require('passport-facebook').Strategy;
const fbConfig = require('./oauth');
const cookieParser = require('cookie-parser');
const session = require('express-session');
    // used to serialize the user for the session
    // Not using these yet
passport.serializeUser(function (user, done) {
  done(null, user.id);
});

passport.deserializeUser(function (obj, done) {
  done(null, obj);
});

const Botly = require('botly');
const botly = new Botly({
  accessToken: process.env.ACCESS_TOKEN,
  verifyToken: '123123321' // the verification token you provided when defining the webhook in facebook
});

const app = express();

// Listen on the account link event
botly.on('account_link', (sender, message, link) => {
    // Continue conversation
  console.log('CONFIRMED AUITH', link);
  botly.sendText({
    id: sender,
    text: (link.status === 'unlinked') ? 'sorry to see you go' : 'Welcome'
  });
});
botly.on('message', (senderId, message, data) => {
  const text = `echo: ${data.text}`;

  botly.sendText({
    id: senderId,
    text: text
  });
  botly.sendButtons({
    id: senderId,
    text: 'Please Login :)',
    buttons: [ botly.createAccountLinkButton(`https://${process.env.LOGIN_DOMAIN}/authorize/?senderId=' + senderId/`), botly.createAccountUnLinkButton() ]
  });
});

app.use(bodyParser.json());
app.use('/', router);

app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({ secret: 'its_my_secret', resave: true, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use('/webhook', botly.router());
app.set('port', port);

  // Passport setup
passport.use('facebook', new FacebookStrategy({
  clientID: fbConfig.facebook.clientID,
  clientSecret: fbConfig.facebook.clientSecret,
  callbackURL: fbConfig.facebook.callbackURL,
  profileFields: [ 'id', 'displayName', 'email' ]

},

  // facebook will send back the tokens and profile
  function (request, access_token, refresh_token, profile, done) {
    // asynchronous
    process.nextTick(function () {
      return done(null, profile);
    });
  }));

/*
 * This path is used for account linking. The account linking call-to-action
 * (sendAccountLinking) is pointed to this URL.
 *
 */
app.get('/authorize', function (req, res, next) {
  req.session.senderId = req.query.senderId;

  console.log('%%%%%%%% AccountLinking Testing');

  const accountLinkingToken = req.query.account_linking_token;
  const redirectURI = req.query.redirect_uri;

  console.log('%%%%% /authorize called with accountLinkingToken %s, redirectURI %s', accountLinkingToken, redirectURI);

  // Authorization Code should be generated per user by the developer. This will
  // be passed to the Account Linking callback.
  const authCode = '1234567890';
  // Redirect users to this URI on successful login
  const redirectURISuccess = `${redirectURI}&authorization_code=${authCode}`;
  LINKED.redirect = redirectURISuccess;
  console.log('redirect to this ', redirectURISuccess);
  passport.authenticate('facebook', { scope: [ 'email' ] },
    {
      state: {
        senderId: req.query.senderId // senderId will be used after auth to reply to the user
      }
    })(req, res, next);
});

        // Redirection after login
app.get('/auth/fb/callback', (req, res, next) => {
  passport.authenticate('facebook', (err, user, info) => {
    if (err) { return next(err); }
    if (!user) {
      console.log('bad', info);
      return res.redirect(LINKED.redirect);
    }
    console.log('good');
    LINKED.user = user;
  })(req, res, next);
  res.redirect(LINKED.redirect);
});

const server = http.createServer(app);
server.listen(port);