programing

Node + Express + Passport : req.user 정의되지 않음

nasanasas 2020. 11. 27. 08:11
반응형

Node + Express + Passport : req.user 정의되지 않음


내 질문은 이것과 유사 하나 , 그러나 그의 솔루션으로 더 통찰력이 없었다.

Instagram을 사용하여 인증하기 위해 Passport를 사용하고 있습니다. 인증이 성공하면 사용자는 "/"로 이동합니다. 이 시점에서 요청에는 사용자 개체 (일명 작동 중)가 있습니다. 그러나 리디렉션하면 req.user가 정의되지 않습니다. : '(

이상한 부분은 각 요청과 함께 passport.deserializeUser가 호출된다는 것입니다. 사용자 객체를 성공적으로 가져 왔지만 미들웨어 도로 어딘가에서 req.user가 설정되지 않았거나 설정되지 않았습니다.

// on successful auth, goto "/" 
app.get('/', function(req, res) {
    // if the request has the user object, go to the user page
    if (req.user) {
        res.redirect("/user/" + req.user._id);
    }

    res.render("index");
}

app.get('/user/:uid', function(req, res) {
    console.log(req.user) // undefined
}

앱의 세션 상태를 설정 했습니까? 이런 게 필요해 ...

app.use(session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());

내 문제는 클라이언트 측에서 가져 오기를 사용할 때 쿠키를 보내도록 지정하지 않았습니다. 요청에 자격 증명 : 'include'필드를 포함시킨 후 작동했습니다.

fetch('/api/foo', {credentials: 'include'})

저는 Node를 처음 접했지만 미들웨어 문제였습니다. bodyParser를 추가하고 재정렬하여 수정했습니다.

깨진 코드 :

app.use(express.cookieParser('secret'));
app.use(express.cookieSession());
app.use(express.session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public'))); 

작업 코드 :

app.use(express.static(path.join(__dirname, 'public')));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);

도움이 되었기를 바랍니다


이전에는 다음 코드가 있습니다 (작동하지 않음).

app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser('abcdefg'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({
    secret: 'abcdefg',
    resave: true,
    saveUninitialized: false,
    cookie: { secure: true } // this line
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));

그런 다음 세션 이니셜 라이저에서 쿠키 옵션을 제거합니다.

app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser('abcdefg'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({
    secret: 'abcdefg',
    resave: true,
    saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));

이제 작동합니다.


예 @Martin이 말하는 것과 같은 세션을 활성화하십시오. 그러나 Express 4. * 버전을 사용하는 경우 세션과 같은 미들웨어가 번들로 제공되지 않으므로 개별적으로 설치해야합니다.

  1. 추가 "세션을 표현하는": "1.4.0"을 당신의 package.json에
  2. npm 설치
  3. 그걸 써

;

var express = require('express');
var cookieParser = require('cookie-parser')
var session = require('express-session')
var app = express()
app.use(cookieParser()) // required before session.
app.use(session({secret: 'keyboard cat'}))

자세한 정보는 Express 세션 문서를 확인하십시오 .


익스프레스 세션 문서에서 다음 코드를 복사하여 붙여 넣기 때문에 동일한 문제가 발생하지만 문서를 완전히 읽지 못합니다.

app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true }
}))

문서에서 다음과 같이 언급했습니다.

그러나 HTTPS가 활성화 된 웹 사이트가 필요합니다. 즉, 보안 쿠키에는 HTTPS가 필요합니다. 보안이 설정되어 있고 HTTP를 통해 사이트에 액세스하면 쿠키가 설정되지 않습니다.

따라서 HTTP 연결 만있는 경우 보안 옵션을 제거하면 아래 코드가 작동합니다.

app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  //cookie: { secure: true } remove this line for HTTP connection
}))

경로에서 다음을 추가해보세요. {session: true}

app.get('/auto-login', passport.authenticate('cross', {session: true}))

나는 Express 4를 사용하여 똑같은 문제를 겪었고 온라인에서 찾을 수있는 거의 모든 것을 시도한 후 마침내 '쿠키 세션'을 추가하여 작동하게했습니다.

var cookieSession = require('cookie-session');

app.use(cookieSession({
  keys: ['key1', 'key2']
}));

내 것은 쿠키와 코르에 관한 것이었다. 내 서버에 다음 코드를 추가하여 해결했습니다.

allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:3000'); // your website
res.header('Access-Control-Allow-Credentials', 'true');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
if ('OPTIONS' === req.method) {
    res.send(200);
} else {
    next();
}};

익스프레스 세션 설정이 완료되면 req.user가 생성 될 때의 역 직렬화 기능에서 패스포트 직렬화 및 역 직렬화가 있는지 확인하십시오. 다른 stackoverflow 질문에서 여기에 대한 설명을 참조하십시오 .

passport.serializeUser(function(user, done) {
 done(null, user);
});


passport.deserializeUser(function(user, done) {
 done(null, user);
});

클라이언트 측에서 http 요청을 사용할 때 자격 증명을 첨부해야합니다. Angular2에서는 {withCredentials : true} 옵션 인수를 추가해야합니다. 이 후에는 다시 재설정 할 때까지 동일한 req.sessionID를 갖게됩니다.

this._http.get("endpoint/something", { withCredentials: true })

내 것은이 모든 것들과 달랐다. 이전에 localhost에서 Wordpress 사이트를 개발 한 다음 별도의 Node / React 프로젝트로 전환했습니다.

Wordpress 사이트의 쿠키는 두 프로젝트가 모두 localhost에서 실행되었으므로 여전히 존재하고 전송되었습니다. 이로 인해 문제가 발생했습니다.

나는 localhost에 대한 쿠키를 지우고 작동했습니다.


미들웨어 스택이 명확하지 않은 경우 세션 미들웨어가 어딘가에 있다고 가정하면 리디렉션 전에 세션을 저장할 수 있습니다.

if (req.user) {
    req.session.save(function (err) {
        if (err) {
            // ... panic!
        }
        res.redirect("/user/" + req.user._id);
    });
    return;
}

cookieParser에 secretKey를 삽입하려고 했습니까?

var passport = require('passport');
var expressSession = require('express-session');

app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser('mySecretKey'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressSession({
secret: 'mySecretKey',
  resave: false,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());

똑같은 문제가있었습니다. 저에게 해결책은 '익스프레스 세션'대신 '클라이언트 세션'을 사용하는 것이 었습니다. 아마도 세션 구성이 잘못 되었나요?

작동하지 않는 코드 :

var session = require('express-session');

app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(session({
    secret: 'random string',
    resave: true,
    saveUninitialized: true,
    cookie: { secure: true }
}));

작동 코드 :

var session = require('client-sessions');

        app.use(bodyParser.urlencoded({ extended: false }));
        app.use(express.static(path.join(__dirname, 'public')));
        app.use(cookieParser());
        app.use(bodyParser.json());
        app.use(session({
        cookieName: 'session',
        secret: 'random string',
        duration: 30 * 60 * 1000,
        activeDuration: 5 * 60 * 1000,
    }));

req.isAuthenticated () 및 req.user 모두 동일한 문제가 발생했습니다. 해결 방법은 다음과 같습니다.

  • req.isAuthenticated ()는 deserialize () 내부의 findById () 메서드에서 findOne ()을 find ()로 대체하여 해결 된 다음 인증 된 req를 저장할 수 있습니다. 그렇지 않으면 아무것도 반환하지 않았습니다.

  • req.user는 순서를 조정하여 해결했습니다. 첫 번째 Express-session을 저장 한 다음 passport를 초기화 한 다음 passport.session ()에 다음 세션을 저장해야합니다. 그 후 passport.session ()에 세션을 저장 한 후 req.user에 액세스 할 수 있습니다.

app.use(session(...));
app.use(passport.initialize());
app.use(passport.session());
// Now we can access req.user so after we will call req.user, if we write it above these, it will always return underfined
app.use(function(req, res, next){
  res.locals.user = req.user || null
  next();
})

passport.session()아래에 경로를 추가하지 않으면 이후 req.user에 액세스하는지 확인하십시오.


While doing passport.authenticate you can add session: true to resolve your issue:

app.post("/login", passport.authenticate('local', {
    'failureRedirect': '/login',
    'session': true
}), (req, res)=>{ res.redirect("/"); });

My two cents: not working code:

server.use(
session({
  secret: "secretsssss",
  rolling: false,
  resave: false,
  saveUninitialized: false,
  cookie: {
    sameSite: true, //this line
    maxAge: 60 * 60 * 1000
  }
})
);

working code:

server.use(
session({
  secret: "secretsssss",
  rolling: false,
  resave: false,
  saveUninitialized: false,
  cookie: {
    sameSite: false, // i think this is default to false
    maxAge: 60 * 60 * 1000
  }
})
);

When you authenticate a user, the request value req.user is filled. To know if the identify the user and fill that value, a cookie is used. If like me, you configure the session with secure cookies, cookies will be available only over HTTPS, which is not the standard configuration for, let's say, a local development server. To have cookies work over HTTP, comment out cookie: { secure: true } and req.user value will be properly configured:

this.app.use(session({
    resave: true,
    saveUninitialized: true,
    secret: process.env.SESSION_SECRET || "a secret",
    // cookie: { secure: true },
}));

If, reasonably, you want cookies over HTTPS only in production, you can do something like:

cookie: { secure: process.env.ENV === 'PRODUCTION' }

Server sends SetCookie header then the browser handle to store it, and then the cookie is sent with requests made to the same server inside a Cookie HTTP header.

I had to set withCredentials: true in my client. (axios.js)

const config = {
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
  },
};

axios.put(url, { page: '123' }, config)
  .then(res => console.log('axios', res))
  .catch(err => console.log('axios', err));

Then CORS problems occur.

So I added this to my express server:

app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Origin', req.headers.origin);
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
  if ('OPTIONS' == req.method) {
    res.send(200);
  } else {
      next();
  }
});

I had a different issue, something with bcrpt-node and arrow functions.

Code that works:

userSchema.methods.generateHash = function (password) {
  return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null); 
};

userSchema.methods.isValidPassword = function (password) {
  return bcrypt.compareSync(password, this.password);
};

Code that does not work:

userSchema.methods.generateHash = (password) => {
  return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

userSchema.methods.isValidPassword = (password) => {
  return bcrypt.compareSync(password, this.password);
};

참고URL : https://stackoverflow.com/questions/16434893/node-express-passport-req-user-undefined

반응형