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

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

新規登録して質問してみよう
ただいま回答率
85.48%
JWT(JSON Web Token)

JWT(JSON Web Token)とは、JSONをベースとしたアクセストークンの仕様。電子署名付きのURL safeなJSONのことを指します。電子署名が付いているため、改ざんをチェックできる点がメリットです。

Node.js

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

Express

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

Q&A

0回答

845閲覧

expressでjwtを使って認証機能を実装したい

yusuke.y

総合スコア17

JWT(JSON Web Token)

JWT(JSON Web Token)とは、JSONをベースとしたアクセストークンの仕様。電子署名付きのURL safeなJSONのことを指します。電子署名が付いているため、改ざんをチェックできる点がメリットです。

Node.js

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

Express

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

0グッド

1クリップ

投稿2021/03/05 18:23

ログイン時にjwtを使ってトークンを作成し、ログイン時のみアクセスできるページに認証機能をつけようとしています。
ログイン時にトークンが作成できているのですが、認証APIが機能していませんでした。
認証時にreq.headers.authorizationにトークンの情報が格納されているはずなのですが、undefinedとなってしまいます。
これは何が原因なのでしょうか?

/my-app/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'); 6 7var indexRouter = require('./routes/index'); 8var usersRouter = require('./routes/users'); 9 10var app = express(); 11 12// view engine setup 13app.set('views', path.join(__dirname, 'views')); 14app.set('view engine', 'ejs'); 15 16app.use(logger('dev')); 17app.use(express.json()); 18app.use(express.urlencoded({ extended: false })); 19app.use(cookieParser()); 20app.use(express.static(path.join(__dirname, 'public'))); 21 22app.use('/', indexRouter); 23app.use('/users', usersRouter); 24 25// catch 404 and forward to error handler 26app.use(function(req, res, next) { 27 next(createError(404)); 28}); 29 30// error handler 31app.use(function(err, req, res, next) { 32 // set locals, only providing error in development 33 res.locals.message = err.message; 34 res.locals.error = req.app.get('env') === 'development' ? err : {}; 35 36 // render the error page 37 res.status(err.status || 500); 38 res.render('error'); 39}); 40 41module.exports = app; 42

/my-app/dockerExpress/routes/index.js

js

1const express = require('express'); 2const router = express.Router(); 3const bodyParser = require('body-parser'); 4const app = require('../app'); 5const registerValidController = require('../controllers/registerValid'); 6const loginValidController = require('../controllers/loginValid'); 7const authenticate = require('../controllers/authenticate'); 8const { body } = require('express-validator'); 9const urlencodedParser = bodyParser.urlencoded({ 10 extended: false 11}); 12 13/* GET home page. */ 14router.get('/', (req, res, next) => { 15 res.render('index'); 16}); 17 18router.get('/register', (req, res) => { 19 res.render('register'); 20}); 21 22router.get('/board', authenticate, (req, res) => { 23 res.render('board'); 24 } 25); 26 27router.post( 28 '/register', 29 urlencodedParser, 30 registerValidController.rootAccessControl.validCheck, 31 registerValidController.rootAccessControl.validResult 32); 33 34router.post( 35 '/index', 36 urlencodedParser, 37 loginValidController.rootAccessControl.validResult 38); 39 40module.exports = router; 41

/my-app/dockerExpress/controllers/loginValid.js

js

1const express = require('express'); 2const jwt = require('jsonwebtoken'); 3const config = require('../config/config'); 4const router = express.Router(); 5const mysql = require('mysql2'); 6const connection = mysql.createConnection({ 7 user: 'root', 8 password: 'root', 9 database: 'my_mysql_db', 10 host: 'my_mysql' 11}); 12 13connection.connect((err) => { 14 if (err) { 15 console.log('error connectiong: ' + err.stack); 16 return; 17 } 18 console.log('success'); 19}); 20 21exports.rootAccessControl = { 22 validResult: (req, res) => { 23 const password = req.body['password']; 24 const email = req.body['email']; 25 if (!password || !email) { 26 const loginErrorMessage1 = 'メールアドレスもしくはパスワードが入力されていません'; 27 res.render('index', { 28 err: loginErrorMessage1 29 }); 30 } else { 31 const columns = ['email', 'password'] 32 connection 33 .query( 34 'select ?? from ?? where email = ? and password = ?', 35 [columns, 'users', email, password], 36 (err, results, fields) => { 37 if (!results[0]) { 38 const loginErrorMessage2 = 'メールアドレスまたはパスワードが間違っています'; 39 res.render('index', { 40 err: loginErrorMessage2 41 }); 42 } else { 43 const queryEmail = results[0].email; 44 const queryPassword = results[0].password; 45 if (queryEmail === email && queryPassword === password) { 46 const payload = { 47 email: email 48 }; 49 const token = jwt.sign(payload, config.jwt.secret, config.jwt.options); 50 const body = { 51 email: email, 52 token: token 53 }; 54 res.json(body); 55 } else { 56 const loginErrorMessage2 = 'メールアドレスまたはパスワードが間違っています'; 57 res.render('index', { 58 err: loginErrorMessage2 59 }); 60 } 61 } 62 }); 63 } 64 } 65} 66

/my-app/dockerExpress/controllers/authenticate.js
これのreq.headers.authorizationがないためトークンを使った認証ができない。
上記のログイン処理をするloginValid.jsでトークンは作成できていることは確認しています。

js

1const jwt = require('jsonwebtoken'); 2const config = require('../config/config'); 3 4module.exports = function authenticate(req, res, next) { 5 console.log(req.headers.authorization); //undefined 6 try { 7 const token = req.headers.authorization; 8 const decoded = jwt.verify(token, config.jwt.secret); 9 console.log(decoded); 10 req.jwtPayload = decoded; 11 next(); 12 } catch (err) { 13 return res.status(401).json({ 14 message: 'Not authenticated' 15 }); 16 } 17} 18

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

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

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

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

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

FromMZ1500

2021/03/06 02:38

難しいこといっぱい盛り込まれていますが、これはよくみかける MySQLのクエリが非同期で results が取れてないという問題では? connection 開いて userテーブルから値とってきて console.log に書く しごく単純な app.js をまずは試されてみてどうでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問