0

修改这个问题,因为我已经取得了一些进展,并且护照推特身份验证主要工作:带有 Express/Knex/Postgresql 后端的 VueJS 应用程序。

问题是我将护照推特与我之前使用 jwt 的本地护照使用结合起来。因此,我必须为新的 Twitter 用户生成一个标头令牌。目前在使用 Twitter 登录时,尚未读取标头令牌。如果没有有效的令牌,应用程序会做一些疯狂、耗时的事情。

这是来自初始 Twitter 登录请求的标头对象,将令牌显示为未定义的对象:

headers:

{ host: 'localhost:8000',
     connection: 'keep-alive',
     accept: 'application/json, text/plain, */*',
     origin: 'http://localhost:8080',
     'user-agent':
      'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
     token: '[object Object]',
     'sec-fetch-mode': 'cors',
     'sec-fetch-site': 'same-site',
     referer:
      'http://localhost:8080/?user=%7B%22id%22%3A10,%22email%22%3Anull,%22token%22%3A%22eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6bnVsbCwiaWQiOjEwLCJleHAiOjE1NzYwNTU1MzYsImlhdCI6MTU3MDg2NzkzNn0.SUYL2KcnK8C9zYNLCcqGF99TjfIRxAcyg0Uc8WjQJD0%22%7D',
     'accept-encoding': 'gzip, deflate, br',
     'accept-language': 'en-US,en;q=0.9',
     'if-none-match': 'W/"79-a0G25cV4V6cfQoTIFr1X/nYU2Kg"' },

刷新浏览器时,标题标记按预期显示,并且错误消失了。

标题:

{ host: 'localhost:8000',
     connection: 'keep-alive',
     accept: 'application/json, text/plain, */*',
     origin: 'http://localhost:8080',
     'user-agent':
      'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
     token:
      'Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6bnVsbCwiaWQiOjEwLCJleHAiOjE1NzYwNTU1MzYsImlhdCI6MTU3MDg2NzkzNn0.SUYL2KcnK8C9zYNLCcqGF99TjfIRxAcyg0Uc8WjQJD0',
     'sec-fetch-mode': 'cors',
     'sec-fetch-site': 'same-site',
     referer:
      'http://localhost:8080/?user=%7B%22id%22%3A10,%22email%22%3Anull,%22token%22%3A%22eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6bnVsbCwiaWQiOjEwLCJleHAiOjE1NzYwNTU1MzYsImlhdCI6MTU3MDg2NzkzNn0.SUYL2KcnK8C9zYNLCcqGF99TjfIRxAcyg0Uc8WjQJD0%22%7D',
     'accept-encoding': 'gzip, deflate, br',
     'accept-language': 'en-US,en;q=0.9',
     'if-none-match': 'W/"79-a0G25cV4V6cfQoTIFr1X/nYU2Kg"' }

以下是 Express 中的相关文件:

authenticate.js 是中间件,我用来从标头中获取令牌:

const jwt = require('express-jwt');

const getTokenFromHeaders = (req) => {
  console.log('req from headers is: ', req)
  const { headers: { token } } = req; // same as token = req.headers.token

  if(token && token.split(' ')[0] === 'Token') {
    return token.split(' ')[1];
  }
  return null;

};

const auth = {
  required: jwt({
    secret: 'secret',
    userProperty: 'user',
    getToken: getTokenFromHeaders,
  }),
  optional: jwt({
    secret: 'secret',
    userProperty: 'user',
    getToken: getTokenFromHeaders,
    credentialsRequired: false,
  }),
};

module.exports = auth;

应用程序.js:

const express = require('express')
const bodyParser = require('body-parser')
const path = require('path')
const dotenv = require('dotenv')
const Knex = require('knex')
const { Model } = require('objection')
const cors = require('cors');
const pathfinderUI = require('pathfinder-ui');
const session = require('express-session');
const passport = require('passport')

dotenv.config()
const app = express()

// objection setup
const knexfile = require('../knexfile')
const knex = Knex(knexfile[process.env.NODE_ENV])
Model.knex(knex)

//Configure our app
app.use('/pathfinder', function (req, res, next) {
  pathfinderUI(app)
  next()
}, pathfinderUI.router);

var corsOptions = {
  origin: '*',
  optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 
}
app.use(cors(corsOptions));

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

var sess = {
  secret: 'keyboard cat',
  cookie: {}
}

if (app.get('env') === 'production') {
  app.set('trust proxy', 1) // trust first proxy
  sess.cookie.secure = true // serve secure cookies
}

app.use(session(sess))
app.use(passport.initialize());
app.use(passport.session());

require('./config/passport');

// api routes
// should we refactor this?
app.use("/api/auth", require("./routes/auth"))
app.use("/api/posts", require("./routes/posts"))
app.use("/api/acts", require("./routes/acts"))
app.use("/api/reports", require("./routes/reports"))
app.use("/api/groups", require("./routes/groups"))
app.use("/api/users", require("./routes/users"))
app.use("/api/memberships", require("./routes/memberships"))
app.use("/api/kudos", require("./routes/kudos"))

app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, "index.html"))
})

module.exports = app

护照.js:

    const passport = require('passport');
    const LocalStrategy = require('passport-local');
    const TwitterStrategy = require('passport-twitter').Strategy
    const authHelpers = require('../auth/helpers');
    var port = process.env.PORT || 8000;
    const User = require('../models/User');

    var trustProxy = false;
    if (process.env.DYNO) {
      // Apps on heroku are behind a trusted proxy
      trustProxy = true;
    }

    passport.use(new LocalStrategy({
      usernameField: 'user[email]',
      passwordField: 'user[password]',
    }, async (email, password, done) => {
      const user = await User.query().where('email', email );
      if (user && user.length === 1 && authHelpers.comparePass(password, user[0].password)) {
        return done(null, user[0]);
      } else {
        return done(null, false, { errors: { 'email or password': 'is invalid' } });
      }
    }));

    passport.use(new TwitterStrategy({
      consumerKey: process.env.TWITTER_CONSUMER_KEY,
      consumerSecret: process.env.TWITTER_SECRET_KEY,
      callbackURL: process.env.TWITTER_CALLBACK_URL, //this will need to be dealt with
      proxy: trustProxy
      }, async function(token, tokenSecret, profile, done) {
        let user = await User.query().findOne({twitter_id: profile.id_str})
        console.log('hitting the passport twitter strategy')
        if (user) {
          // todo: update user with twitter profile
          return done(null, user);
        } else {
            user = await authHelpers.createTwitterUser(profile);
            console.log("The User from createTwitterUser is " + user);
            return done(null, user);
        }
    }));

auth.js:

const express = require('express');
const User = require('../models/User');
const auth = require('../middlewares/authenticate');
const passport = require('passport');
const authHelpers = require('../auth/helpers')

let router = express.Router();

...

router.get('/twitter',
  passport.authenticate('twitter')
);

router.get('/twitter/callback', 
  passport.authenticate('twitter', { failureRedirect: process.env.VUE_LOGIN_URL}),
  function(req, res) {
    // Successful authentication, redirect home.
    const user = JSON.stringify(req.user);
    console.log('hittingthe callback routesending stringified user: ', user);
    res.redirect(process.env.VUE_HOME_URL + '?user=' + user);
  });

module.exports = router;

helpers.js:

const bcrypt = require('bcryptjs');
const User = require('../models/User');
const jwt = require('jsonwebtoken');

...

async function createTwitterUser(profile) {
  let newUser = await User.query()
    .insert({
      username: profile.screen_name,
      bio: profile.description,
      location: profile.location,
      avatar: profile.profile_image_url_https,
      twitter_id: profile.id_str //change to int 
    })
    .returning('*');
  console.log("new User is: ", newUser);
  return newUser;
}
...   
    module.exports = {
      comparePass,
      createUser,
      toAuthJSON
    };
4

0 回答 0