開発環境
現在、ローカル環境での開発でTwitter認証を用いたwebアプリケーションを開発しています。
Docker、Expressを用いています。
動作確認の際、GoogleChromeとFirefoxの2画面でそれぞれ異なるTwitterアカウントで認証してテストしています。
Twitter認証にはpassport.jsを用いています。
バグの内容
最初にTwitter認証した人のセッションが、後からTwitter認証した人のセッションに書き換えられてしまいます。
これはpassport.session.idに保存したTwitterアカウントIDが上書きされていることから発覚しました。
質問内容
2画面の異なるブラウザないしは同じブラウザで動作確認を行う際に、Twitter認証を通した後にセッションが書き換えられないようにしたいです。
どのような処理をしたら良いでしょうか?
コード
以上のバグを解決するにあたって必要なコードを掲載します。
不備がありましたら教えてくださいますと助かります。すぐに追記いたします。
ディレクトリ構造
twipoke |-docker-compose.debug.yml |-docker-compose.yml |-twipoke |-bin |-node_modules |-public |-routes | |-index.js | |-views | |-home.ejs | |-index.ejs | |-app.js |-Dockerfile |-package-lock.json |-package.json
Dockerfile
dockerfile
1FROM node:12.18-alpine 2WORKDIR /usr/src/app 3COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"] 4RUN npm install 5COPY . . 6EXPOSE 3000 7CMD ["npm", "start"]
docker-compose.yml
yml
1version: '3.4' 2 3services: 4 twipoke: 5 image: dockerexpress 6 build: 7 context: twipoke 8 dockerfile: ./Dockerfile 9 ports: 10 - 3000:3000 11
app.js
js
1var createError = require('http-errors'); 2var express = require('express'); 3var path = require('path'); 4var cookieParser = require('cookie-parser'); 5var logger = require('morgan'); 6var twitterConfig = require('./config/twitter_config'); 7var indexRouter = require('./routes/index'); 8 9// TwitterAPI設定----------------------- 10var passport = require('passport'); 11var session = require('express-session'); 12var TwitterStrategy = require('passport-twitter').Strategy; 13var TWITTER_CONSUMER_KEY = twitterConfig.consumer_key; 14var TWITTER_CONSUMER_SECRET = twitterConfig.consumer_secret; 15passport.serializeUser(function (user, done) { 16 done(null, user.id); 17}); 18passport.deserializeUser(function (obj, done) { 19 done(null, obj); 20}); 21passport.use(new TwitterStrategy({ 22 consumerKey: TWITTER_CONSUMER_KEY, 23 consumerSecret: TWITTER_CONSUMER_SECRET, 24 callbackURL: "http://localhost:3000/auth/twitter/callback" //本番環境はここを変える 25}, function (token, tokenSecret, profile, done) { 26 passport.session.id = profile.id; 27 passport.session.twitter_token = token; 28 passport.session.twitter_token_secret = tokenSecret; 29 profile.twitter_token = token; 30 profile.twitter_token_secret = tokenSecret; 31 process.nextTick(() => { 32 return done(null, profile); 33 }); 34})); 35//--------------------------------------- 36 37var app = express(); 38 39// view engine setup 40app.set('views', path.join(__dirname, 'views')); 41app.set('view engine', 'ejs'); 42 43app.use(logger('dev')); 44app.use(express.json()); 45app.use(express.urlencoded({ extended: false })); 46app.use(cookieParser()); 47app.use(express.static(path.join(__dirname, 'public'))); 48app.use(express.static(path.join(__dirname, 'node_modules/socket.io/client-dist'))); 49// -------------------------- 50app.use(passport.initialize()); 51app.use(passport.session()); 52app.use(session({secret: 'secret'})); 53// -------------------------- 54 55app.use('/', indexRouter); 56 57// catch 404 and forward to error handler 58app.use(function(req, res, next) { 59 next(createError(404)); 60}); 61 62// error handler 63app.use(function(err, req, res, next) { 64 // set locals, only providing error in development 65 res.locals.message = err.message; 66 res.locals.error = req.app.get('env') === 'development' ? err : {}; 67 68 // render the error page 69 res.status(err.status || 500); 70 res.render('error'); 71}); 72 73module.exports = app; 74
index.js
js
1var express = require('express'); 2var router = express.Router(); 3var passport = require('passport'); 4var loginController = require('../controllers/login'); 5var userInfoController = require('../controllers/userInfo'); 6var matchPreparationController = require('../controllers/matchPreparation'); 7 8/* GET home page. */ 9router.get('/', (req, res, next) => { 10 res.render('index'); 11}); 12 13// twitter login OAuth------------------ 14router.post('/auth/twitter', passport.authenticate('twitter')); 15router.get('/auth/twitter/callback', passport.authenticate('twitter', { successRedirect: '/home', failureRedirect: '/' })); 16router.get('/home', loginController); 17// ------------------------------------- 18 19// GET battle room create page 20router.get('/room/:id', userInfoController); 21 22router.get('/search', (req, res) => { 23 res.render('search'); 24}); 25 26router.get('/matchPreparation/:id', matchPreparationController); 27 28module.exports = router; 29
index.ejs
js
1<!DOCTYPE html> 2<html> 3 <head> 4 <title>twipoke</title> 5 <link rel='stylesheet' href='/stylesheets/style.css' /> 6 <meta name="viewport" content="width=device-width,initial-scale=1"> 7 </head> 8 <body> 9 <div class="app-title"> 10 <h1>Twipoke</h1> 11 <p>twitterフォロワーで対戦するアプリ</p> 12 </div> 13 <div class="app-image-container"> 14 <div class="left-arrow"></div> 15 <div class="app-images"></div> 16 <div class="right-arrow"></div> 17 </div> 18 <div class="app-info"> 19 <p> 20 レート・ランキング機能対応 21 </p> 22 <p> 23 あなたのフォロワーで競い合おう!! 24 </p> 25 </div> 26 <form action="auth/twitter" method="POST"> 27 <button type submit>twitter</button> 28 </form> 29 </body> 30</html> 31
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/10 13:37
2021/06/10 14:00