質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

セッション

Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Q&A

解決済

2回答

3070閲覧

同じブラウザで異なるセッションを管理したい

yusuke.y

総合スコア17

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

セッション

Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

0グッド

1クリップ

投稿2021/06/10 04:12

開発環境

現在、ローカル環境での開発で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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

自己解決しました。

sessionとcookieの理解が甘かったです。
ブラウザではcookieに任意のデータを記録するのがスマートでしたので、sessionに格納されたデータを使うのはナンセンスでした。
そのため、Twitter認証を通した時、passport.sessionに格納された諸データをcookie-parserを使ってcookieに移動させる必要がありました。

【下記認識で合っていると思いますが間違っていましたらご指摘ください】
sessionはローカルに保存されるデータのため、2画面でブラウザを起動したとしても後から通したTwitter認証データに上書きされてしまいます。
cookieであればブラウザごとにデータが保存されるため、今回のようなバグは発生しないようです。

投稿2021/06/10 06:34

yusuke.y

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ockeghem

2021/06/10 13:37

> 【下記認識で合っていると思いますが間違っていましたらご指摘ください】 間違っていますよ。しかし、解決したのですよね
yusuke.y

2021/06/10 14:00

勉強不足で恐縮です。 一連のバグは解決しました。
guest

0

違う種類のブラウザを併用してもらう事が現実的だと思います。

ブラウザの拡張機能でそういうのがあれば、拡張機能を使っている人は解決できますが、コード側で解決することはできないと思います。
(私の知識不足ならごめんなさい)

投稿2021/06/10 04:31

hiro_app

総合スコア123

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hiro_app

2021/06/10 04:38

実現しようとすると ・ログイン機能周りの大改修 普通ログイン済みかをセッション等で判断していると思いますが、セッションがあるのにログイン画面には入って新規でログインしたい。 なら、ログイン画面以外にブックマーク等で直接アクセスされたら誰がログインしている状態とするのか? つまり、ログイン画面以外はブックマーク、URLアクセスもできないような制限が必要になるのでは? また、ブックマーク等のアクセスを制限するなら、画面遷移関連の処理も一通り制御をかけて、試験をやり直しになるのでは? ・セッションを廃止 セッションに頼って実装している機能を軒並み別手段で実装し直す 超小規模ならできると思いますが・・・、基本的にどちらも非現実的だと思います。 中には例外もありますが、世の中にあるブラウザwebシステムで、ログイン情報は上書きが普通だと思います。
yusuke.y

2021/06/10 04:45 編集

例えば現在の実装でデプロイしたとして、同じ現象は起きますか? aさんのログイン認証後にbさんがログイン認証をして、aさんがリロードするとbさんのデータに起きかわってしまうと言った具合に。 ちなみに異なるブラウザ(GoogleChromeとFirefoxまたはsafari)で動作確認をしていますがバグは発生しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問