강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

이경록님의 프로필 이미지
이경록

작성한 질문수

[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지

passport.authenticate is not a function 도와주세요..

해결된 질문

작성

·

472

0

passport.authenticate is not a function

TypeError: passport.authenticate is not a function
    at exports.login (/home/node/app/controllers/auth.js:26:14)
    at Layer.handle [as handle_request] (/home/node/app/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/node/app/node_modules/express/lib/router/route.js:144:13)
    at exports.isNotLoggedIn (/home/node/app/middlewares/index.js:15:9)
    at Layer.handle [as handle_request] (/home/node/app/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/node/app/node_modules/express/lib/router/route.js:144:13)
    at Route.dispatch (/home/node/app/node_modules/express/lib/router/route.js:114:3)
    at Layer.handle [as handle_request] (/home/node/app/node_modules/express/lib/router/layer.js:95:5)
    at /home/node/app/node_modules/express/lib/router/index.js:284:15
    at Function.process_params (/home/node/app/node_modules/express/lib/router/index.js:346:12)

POST /auth/login 500 34.609 ms - 2536

GET /main.css 304 2.895 ms - -
현재 로그인을 눌렀을 때 이 오류가 생깁니다.

해결방법을 모르겠습니다..

localStrategy.js

const passport = require('passport');
const {Strategy: localStrategy} = require('passport-local');
const User = require('../models/user');
const bcrypt = require('bcrypt');

module.exports = () => {
    passport.use(new localStrategy({
        usernameField: 'email', 
        passwordField: 'password',
        passReqToCallback: 'false' 
    }, async (email, password, done) => {
        try {
            const exUser = await User.findOne({ where: {email}});
            if (exUser) {
                const result = await bcrypt.compare(passport, exUser.passport); 
                if(result) {
                    done(null, exUser); 
                }
                else {
                    done(null, false, {message: '비밀번호가 일치하지 않습니다.'});
                }
            } else {
                done(null, false, {message: '가입되지 않은 회원입니다.'}); 
            }
        } catch(error) {
            console.error(error);
            done(error); 
        }
    }));
};

controllers/auth.js

const User = require("../models/user");
const bcrypt = require('bcrypt');
const passport = require("../passport");

exports.join = async (req, res, next) => {
    const {nick, email, password} = req.body;
    try {
        const exUser = await User.findOne({ where: {email}});
        if (exUser) {
            return res.redirect('/join?error=exist');
        }
        const hash = await bcrypt.hash(password, 12); 
        await User.create({
            email,
            nick,
            password: hash,
        });
        return res.redirect('/');
    } catch (error) {
        console.error(error);
        next(error);
    }
}
//POST /auth/login
exports.login = (req, res, next) => {
    passport.authenticate('local', (authError, user, info) => {
        if (authError) {
            console.error(authError);
            return next(authError);
        }
        if (!user) { 
            return res.redirect(`/?loginError=${info.message}`);
        }
        return req.login(user, (loginError) => { 
            if (loginError) {
                console.error(loginError);
                return next(loginError);
            }
            return res.redirect('/');
        });
    })(req, res, next); 
};

exports.logout = (req, res, next) => { 
    req.logout(() => {
        res.redirect('/');
    })
}

 

 

app.js

const express = require('express');
const cookieParser = require('cookie-parser');
const morgan = require('morgan');
const path = require('path');
const session = require('express-session');
const nunjucks = require('nunjucks');
const dotenv = require('dotenv');
const passport = require('passport'); 


dotenv.config(); // process.env

const pageRouter = require('./routes/page');
const authRouter = require('./routes/auth');
const { sequelize } = require('./models');
const passportConfig = require('./passport'); 

const app = express();
passportConfig(); 
app.set('port', process.env.PORT || 8080);
app.set('view engine', 'html');
nunjucks.configure('views', {
    express: app,
    watch: true,
});

sequelize.sync({ force: false })
  .then(() => {
    console.log('데이터베이스 연결 성공');
  })
  .catch((err) => {
    console.error(err);
  });

app.use(morgan('dev')); 
app.use(express.static(path.join(__dirname, 'public'))); 
app.use(express.json()); 
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET)); 
app.use(session({
    resave: false,
    saveUninitialized: false,
    secret: process.env.COOKIE_SECRET,
    cookie: {
        httpOnly: true, 
        secure: false, 
    },
}));

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

app.use('/', pageRouter);
app.use('/auth', authRouter);

app.use((req, res, next) => {
  const error =  new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
  error.status = 404;
  next(error);
});

app.use((err, req, res, next) => {
  res.locals.message = err.message;
  res.locals.error = process.env.NODE_ENV !== 'production' ? err : {};
  res.status(err.status || 500);
  res.render('error');
});

app.listen(app.get('port'), () => {
  console.log(app.get('port'), '번 포트에서 대기중');
});

답변 1

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

const passport = require("../passport");

->

const passport = require("passport");

이경록님의 프로필 이미지
이경록
질문자

늦은시간 답변 감사합니다. 그렇게도 수정해보았는데 이렇게 뜹니다.
Error: Invalid value <ref *1> IncomingMessage {

_events: {

close: undefined,

error: undefined,

data: undefined,

end: undefined,

readable: undefined,

aborted: undefined

},

_readableState: ReadableState {

highWaterMark: 16384,

buffer: [],

bufferIndex: 0,

length: 0,

pipes: [],

awaitDrainWriters: null,

[Symbol(kState)]: 60295036

},

_maxListeners: undefined,

socket: Socket {

connecting: false,

_hadError: false,

_parent: null,

_host: null,

_closeAfterHandlingError: false,

_events: [Object],

_readableState: [ReadableState],

_writableState: [WritableState],

allowHalfOpen: true,

_maxListeners: undefined,

_eventsCount: 8,

_sockname: null,

_pendingData: null,

_pendingEncoding: '',

server: [Server],

_server: [Server],

parser: [HTTPParser],

on: [Function: socketListenerWrap],

addListener: [Function: socketListenerWrap],

prependListener: [Function: socketListenerWrap],

setEncoding: [Function: socketSetEncoding],

_paused: false,

_httpMessage: [ServerResponse],

_peername: [Object],

[Symbol(async_id_symbol)]: 188,

[Symbol(kHandle)]: [TCP],

[Symbol(lastWriteQueueSize)]: 0,

[Symbol(timeout)]: null,

[Symbol(kBuffer)]: null,

[Symbol(kBufferCb)]: null,

[Symbol(kBufferGen)]: null,

[Symbol(shapeMode)]: true,

[Symbol(kCapture)]: false,

[Symbol(kSetNoDelay)]: true,

[Symbol(kSetKeepAlive)]: false,

[Symbol(kSetKeepAliveInitialDelay)]: 0,

[Symbol(kBytesRead)]: 0,

[Symbol(kBytesWritten)]: 0

},

httpVersionMajor: 1,

httpVersionMinor: 1,

httpVersion: '1.1',

complete: true,

rawHeaders: [

'Host',

#############

'Connection',

'keep-alive',

'Content-Length',

'49',

'Cache-Control',

'max-age=0',

'Upgrade-Insecure-Requests',

'1',

'Origin',

################

'Content-Type',

'application/x-www-form-urlencoded',

'User-Agent',

'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',

'Accept',

'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',

'Referer',

#################

'Accept-Encoding',

'gzip, deflate',

'Accept-Language',

'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7,ja;q=0.6,zh-TW;q=0.5,zh;q=0.4',

'Cookie',

'pma_lang=ko; pmaUser-1=Eznxj%2FP7WVm6r16G4dFA2qvI3pCqc0Pe8e1ofg97XIf85aHWVlHqBteVfxwn8g%3D%3D; phpMyAdmin=44e320720720513015eabc6c207209bc'

],

rawTrailers: [],

joinDuplicateHeaders: null,

aborted: false,

upgrade: false,

url: '/login',

method: 'POST',

statusCode: null,

statusMessage: null,

client: Socket {

connecting: false,

_hadError: false,

_parent: null,

_host: null,

_closeAfterHandlingError: false,

_events: [Object],

_readableState: [ReadableState],

_writableState: [WritableState],

allowHalfOpen: true,

_maxListeners: undefined,

_eventsCount: 8,

_sockname: null,

_pendingData: null,

_pendingEncoding: '',

server: [Server],

_server: [Server],

parser: [HTTPParser],

on: [Function: socketListenerWrap],

addListener: [Function: socketListenerWrap],

prependListener: [Function: socketListenerWrap],

setEncoding: [Function: socketSetEncoding],

_paused: false,

_httpMessage: [ServerResponse],

_peername: [Object],

[Symbol(async_id_symbol)]: 188,

[Symbol(kHandle)]: [TCP],

[Symbol(lastWriteQueueSize)]: 0,

[Symbol(timeout)]: null,

[Symbol(kBuffer)]: null,

[Symbol(kBufferCb)]: null,

[Symbol(kBufferGen)]: null,

[Symbol(shapeMode)]: true,

[Symbol(kCapture)]: false,

[Symbol(kSetNoDelay)]: true,

[Symbol(kSetKeepAlive)]: false,

[Symbol(kSetKeepAliveInitialDelay)]: 0,

[Symbol(kBytesRead)]: 0,

[Symbol(kBytesWritten)]: 0

},

_consuming: true,

_dumped: false,

next: [Function: next],

baseUrl: '/auth',

originalUrl: '/auth/login',

_parsedUrl: Url {

protocol: null,

slashes: null,

auth: null,

host: null,

port: null,

hostname: null,

hash: null,

search: null,

query: null,

pathname: '/login',

path: '/login',

href: '/login',

_raw: '/login'

},

params: {},

query: {},

res: ServerResponse {

_events: [Object: null prototype],

_eventsCount: 2,

_maxListeners: undefined,

outputData: [],

outputSize: 0,

writable: true,

destroyed: false,

_last: false,

chunkedEncoding: false,

shouldKeepAlive: true,

maxRequestsOnConnectionReached: false,

_defaultKeepAlive: true,

useChunkedEncodingByDefault: true,

sendDate: true,

_removedConnection: false,

_removedContLen: false,

_removedTE: false,

strictContentLength: false,

_contentLength: null,

_hasBody: true,

_trailer: '',

finished: false,

_headerSent: false,

_closed: false,

_header: null,

_keepAliveTimeout: 5000,

_onPendingData: [Function: bound updateOutgoingData],

req: [Circular *1],

_sent100: false,

expectcontinue: false,

_maxRequestsPerSocket: 0,

locals: [Object: null prototype],

_startAt: undefined,

_startTime: undefined,

writeHead: [Function: writeHead],

__onFinished: [Function],

end: [Function: end],

[Symbol(shapeMode)]: false,

[Symbol(kCapture)]: false,

[Symbol(kBytesWritten)]: 0,

[Symbol(kNeedDrain)]: false,

[Symbol(corked)]: 0,

[Symbol(kChunkedBuffer)]: [],

[Symbol(kChunkedLength)]: 0,

[Symbol(kSocket)]: [Socket],

[Symbol(kOutHeaders)]: [Object: null prototype],

[Symbol(errored)]: null,

[Symbol(kHighWaterMark)]: 16384,

[Symbol(kRejectNonStandardBodyWrites)]: false,

[Symbol(kUniqueHeaders)]: null

},

_startAt: [ 377466, 588590538 ],

_startTime: 2023-12-20T16:47:53.461Z,

_remoteAddress: '::ffff:192.168.32.1',

body: [Object: null prototype] {

email:#############

password: ##########

},

_body: true,

length: undefined,

_eventsCount: 0,

secret: 'cookiesecret',

cookies: {

pma_lang: 'ko',

'pmaUser-1': 'Eznxj/P7WVm6r16G4dFA2qvI3pCqc0Pe8e1ofg97XIf85aHWVlHqBteVfxwn8g==',

phpMyAdmin: '44e320720720513015eabc6c207209bc'

},

signedCookies: [Object: null prototype] {},

_parsedOriginalUrl: Url {

protocol: null,

slashes: null,

auth: null,

host: null,

port: null,

hostname: null,

hash: null,

search: null,

query: null,

pathname: '/auth/login',

path: '/auth/login',

href: '/auth/login',

_raw: '/auth/login'

},

sessionStore: MemoryStore {

_events: [Object: null prototype],

_eventsCount: 2,

_maxListeners: undefined,

sessions: [Object: null prototype] {},

generate: [Function (anonymous)],

[Symbol(shapeMode)]: false,

[Symbol(kCapture)]: false

},

sessionID: '2CEG5V0KgCb59NaV2wb0mb8jk2whIXLb',

session: Session { cookie: [Object] },

logIn: [Function (anonymous)],

login: [Function (anonymous)],

logOut: [Function (anonymous)],

logout: [Function (anonymous)],

isAuthenticated: [Function (anonymous)],

isUnauthenticated: [Function (anonymous)],

_sessionManager: SessionManager {

_key: 'passport',

_serializeUser: [Function: bound ]

},

_passport: { instance: [Authenticator] },

route: Route { path: '/login', stack: [Array], methods: [Object] },

[Symbol(shapeMode)]: true,

[Symbol(kCapture)]: false,

[Symbol(kHeaders)]: {

host: #############

connection: 'keep-alive',

'content-length': '49',

'cache-control': 'max-age=0',

'upgrade-insecure-requests': '1',

origin: ###############

'content-type': 'application/x-www-form-urlencoded',

'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',

accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',

referer: #############

'accept-encoding': 'gzip, deflate',

'accept-language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7,ja;q=0.6,zh-TW;q=0.5,zh;q=0.4',

cookie: 'pma_lang=ko; pmaUser-1=Eznxj%2FP7WVm6r16G4dFA2qvI3pCqc0Pe8e1ofg97XIf85aHWVlHqBteVfxwn8g%3D%3D; phpMyAdmin=44e320720720513015eabc6c207209bc'

},

[Symbol(kHeadersCount)]: 26,

[Symbol(kTrailers)]: null,

[Symbol(kTrailersCount)]: 0

}

at Object.escape (/home/node/app/node_modules/sequelize/lib/sql-string.js:53:11)

at MySQLQueryGenerator.escape (/home/node/app/node_modules/sequelize/lib/dialects/abstract/query-generator.js:763:22)

at MySQLQueryGenerator.whereItemQuery (/home/node/app/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1821:102)

at /home/node/app/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1734:25

at Array.forEach (<anonymous>)

at MySQLQueryGenerator.whereItemsQuery (/home/node/app/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1732:35)

at /home/node/app/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1840:30

at Array.map (<anonymous>)

at MySQLQueryGenerator._whereGroupBind (/home/node/app/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1839:21)

at MySQLQueryGenerator.whereItemQuery (/home/node/app/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1790:19)

/home/node/app/passport/localStrategy.js:27

done(error); // 서버실패

^

TypeError: done is not a function

at Strategy._verify (/home/node/app/passport/localStrategy.js:27:13)

at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Node.js v21.4.0

[nodemon] app crashed - waiting for file changes before starting...

 

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

/home/node/app/passport/localStrategy.js:27

 

done(error); // 서버실패

done is not a function

여기에 에러 원인 나오네요

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

passReqToCallback: 'false'

이경록님의 프로필 이미지
이경록
질문자

   const result = await bcrypt.compare(passport, exUser.passport); 

password로 해야하는데 잘못봐서 passport로 작성했네요


passReqToCallback: 'false'
이 부분 지우니까 잘 됩니다. 늦은 시간 답변해주셔서 다시 한번 감사합니다.

이경록님의 프로필 이미지
이경록

작성한 질문수

질문하기