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

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

CSRF

クロスサイトリクエストフォージェリ (Cross site request forgeries、CSRF)は、 外部Webページから、HTTPリクエストによって、 Webサイトの機能の一部が実行されてしまうWWWにおける攻撃手法です。

Express

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

Q&A

解決済

1回答

1039閲覧

JavaScript: Expressでcsrfがうまく動作しない

Nippun

総合スコア1147

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

CSRF

クロスサイトリクエストフォージェリ (Cross site request forgeries、CSRF)は、 外部Webページから、HTTPリクエストによって、 Webサイトの機能の一部が実行されてしまうWWWにおける攻撃手法です。

Express

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

0グッド

1クリップ

投稿2018/04/17 01:20

編集2018/04/17 02:46

JavaScriptとExpressでcsrfがうまく動作しないです。
うまくいけばejsで書いた部分が表示されるはずなのですが'req.csrfToken() is not a function'と言う表示が出てしまいます。

npm i mongoose csurf express-session method-override connect-flash --s

で必要なものはインストールしました。

参考にしたサイト

app.js

javascript

1require('./db/mongo'); 2 3const createError = require('http-errors'); 4const express = require('express'); 5const path = require('path'); 6const cookieParser = require('cookie-parser'); 7const logger = require('morgan'); 8 9const session = require("express-session"); 10const csurf = require("csurf"); 11const mongoose = require("mongoose"); 12const flash = require("connect-flash"); 13const methodOverride = require("method-override"); 14const bodyParser = require('body-parser'); 15 16const indexRouter = require('./routes/index'); 17const usersRouter = require('./routes/users'); 18 19const app = express(); 20 21mongoose.connect('mongodb://localhost/practice'); 22 23// view engine setup 24app.set('views', path.join(__dirname, 'views')); 25app.set('view engine', 'ejs'); 26 27app.use(logger('dev')); 28app.use(express.json()); 29app.use(bodyParser.json()); 30app.use(express.urlencoded({ extended: false })); 31app.use(bodyParser.urlencoded({ extended: false })); 32app.use(cookieParser()); 33app.use(express.static(path.join(__dirname, 'public'))); 34 35app.use('/', indexRouter); 36app.use('/users', usersRouter); 37 38// catch 404 and forward to error handler 39app.use(function(req, res, next) { 40 next(createError(404)); 41}); 42 43// error handler 44app.use(function(err, req, res, next) { 45 // set locals, only providing error in development 46 res.locals.message = err.message; 47 res.locals.error = req.app.get('env') === 'development' ? err : {}; 48 49 // render the error page 50 res.status(err.status || 500); 51 res.render('error'); 52}); 53 54 55app.use(methodOverride(function(req, res){ 56 if( req.body && typeof req.body === "object" && "_method" in req.body ){ 57 const method = req.body._method; 58 delete req.body._method; 59 return method; 60 } 61})); 62 63app.use(session({ 64 secret: 'a', 65 resave: false, 66 saveUninitialized: false, 67 cookie: { 68 httpOnly: true, 69 secure: true, 70 maxage: 1000 * 60 * 30 // 30 minutes 71 } 72})); 73app.use(csurf()); 74app.use(flash()); 75 76module.exports = app; 77

index.js

javascript

1router.get('/new', function (req, res) { 2 res.render('new', { 3 title: 'Add message', 4 reqCsrf: req.csrfToken(), 5 }) 6});

index.ejs

javascript

1<form action="/create" method="post"> 2 <input type="hidden" name="_csrf" value="<%= reqCsrf %>"> 3 <p> 4 <input type="text" name="title" value="" size="60"> 5 <% if( errors && errors.title ){ %> 6 <strong><%= errors.title.message %></strong> 7 <% } %> 8 </p> 9 <p><textarea name="contents" cols="60" rows="12"></textarea></p> 10 <p><button type="submit">Create</button></p> 11</form>

どのようにすれば動くようになるでしょうか?
できればコードの大きな改変をせずに動作させるようにしたいです。

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

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

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

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

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

m.ts10806

2018/04/17 01:31

調べてみたこと、やってみたことを追記してください。また参考先サイトがあればURLも質問に追記してください。既に見た先が回答についてしまうと無駄なやり取りが発生しますし、もしかしたら参考記事の理解が間違っているために解決に至れていないのかもしれません。
Nippun

2018/04/17 01:53

修正しました
HayatoKamono

2018/04/17 02:22 編集

app.use(csurf());より上の行に書かれてるコードを省略せずに記載してください。おそらく、そこに答えがあると思います。というか、試したことの中に公式ドキュメントを読むというのがないので、そちらを読めば解決すると思います。https://github.com/expressjs/csurf/blob/master/README.md
m.ts10806

2018/04/17 02:22

「うまく動作しない」「うまくいかない」では何が起きているか伝わりません。「○○のようになるはずなのに××となってしまう」のような形で「ゴール」と「現象」を明確にしてください。https://teratail.com/help/question-tips#questionTips3-4-1
Nippun

2018/04/17 02:34

情報不足ですみません。追加しました。
HayatoKamono

2018/04/17 02:42 編集

上から2つ目のコードブロックは何という名前のファイルに書かれてるものなのですか?
Nippun

2018/04/17 02:45

view のindex.jsです。
HayatoKamono

2018/04/17 02:47

これのことですか? -> const indexRouter = require('./routes/index');
Nippun

2018/04/17 02:49

そうです。viewでなくroutesです。すみませんでした。
guest

回答1

0

ベストアンサー

参考にされている記事の中盤に「app.jsの編集」という見出しのセクションがありますが、そこにあるコードをもう一度よく確認してみて下さい。

app.use(csurf()); app.use(flash()); app.use('/', routes); app.use('/users', users);

参考にされているサイトのコードを見ると、このようにcsurfミドルウェアの設定を各ルートの設定よりも先に行なっています。

この順序が逆転してしまうと、csurfミドルウェアの設定が行われていない状態で、各ルートがリクエストを処理することになるので、今回のエラーメッセージが出てしまうと思われます。

動作未確認ですが、一度、順序の変更を試してみて下さい。

また、あわせてこの機会にexpressのmiddlewareの仕組みを確認されることをお勧めいたします。

http://expressjs.com/ja/guide/writing-middleware.html
http://expressjs.com/ja/guide/using-middleware.html

投稿2018/04/17 02:59

HayatoKamono

総合スコア2415

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

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

Nippun

2018/04/17 03:07

動きました!! ありがとうございます。 順序は関係ないと思っていました。 素晴らしい観察眼ですね!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問