gpt4 book ai didi

javascript - 跨域Nodejs认证

转载 作者:数据小太阳 更新时间:2023-10-29 04:18:55 24 4
gpt4 key购买 nike

我正在开发一个 MEAN 应用程序,我正在为我的项目使用 Angular 4。对于身份验证,我已经实现了 Passport js Local-strategy .我正在使用 Express-session 维护持久 session .到目前为止一切正常。

问题

在同一个域中,session 工作正常,我能够对用户进行身份验证。但是在跨域中,我无法保持 session 。它为跨域中的每个新请求生成一个新的 session ID。

然后我尝试了 Passport-jwt但问题是我无法控制用户 session 。我的意思是,如果用户处于非事件状态,我无法从服务器注销用户,甚至在服务器重新启动时,token 也不会失效。

所以简单来说,我正在寻找 Node js (Express js) 中的身份验证解决方案,我可以在其中管理跨域身份验证。

我已经看过一些博文和诸如 this 之类的问题, 但它没有帮助。

谢谢。

编辑

我应该自己编写代码来实现吗?如果是这样,我有一个计划。

我的基本计划是:

  1. 用户将在登录请求中发送凭据。
  2. 我将检查数据库中的凭据。如果凭据有效,我将生成一个随机 token 并将其保存到数据库中的用户表中,我将在成功响应时向用户提供相同的 token 。
  3. 现在,对于每个请求,用户将发送 token ,我将检查数据库中每个请求的 token 。如果 token 有效,那么我将允许用户访问 API,否则我将生成带有 401 状态代码的错误。
  4. 我使用的是 Mongoose (MongoDB),所以我可以检查每个请求中的 token (从性能 Angular 来看)。

我觉得这也是个好主意。我只是想要一些建议,不管我的思考方向是否正确。

我会得到什么:

  1. 应用程序中的登录用户数(事件 session )。
  2. 如果用户空闲一段时间,我可以注销他。
  3. 我可以管理同一用户的多个登录 session (通过在数据库中输入一个条目)。
  4. 我可以允许最终用户清除所有其他登录 session (例如 Facebook 和 Gmail 优惠)。
  5. 任何与授权相关的定制。

编辑 2

在这里分享我的app.js代码

var express = require('express');
var helmet = require('helmet');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var dotenv = require('dotenv');
var env = dotenv.load();
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var session = require('express-session');
var cors = require('cors');

var databaseUrl = require('./config/database.js')[process.env.NODE_ENV || 'development'];
// configuration
mongoose.connect(databaseUrl); // connect to our database

var app = express();

// app.use(helmet());

// required for passport


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();
}
});


app.use(cookieParser());

app.use(session({
secret: 'ilovescotchscotchyscotchscotch', // session secret
resave: true,
saveUninitialized: true,
name: 'Session-Id',
cookie: {
secure: false,
httpOnly: false
}
}));


require('./config/passport')(passport); // pass passport for configuration

var index = require('./routes/index');
var users = require('./routes/user.route');
var seeders = require('./routes/seeder.route');
var branches = require('./routes/branch.route');
var companies = require('./routes/company.route');
var dashboard = require('./routes/dashboard.route');
var navigation = require('./routes/navigation.route');
var roles = require('./routes/role.route');
var services = require('./routes/services.route');

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session

require('./routes/auth.route')(app, passport);
app.use('/', index);
app.use('/users', users);
app.use('/seed', seeders);
app.use('/branches', branches);
app.use('/companies', companies);
app.use('/dashboard', dashboard);
app.use('/navigation', navigation);
app.use('/roles', roles);
app.use('/services', services);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
res.status(404).send({ status: 'NOT_FOUND', message: 'This resource is not available.'});
});

// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page
let errorObj = {
status: 'INTERNAL_SERVER_ERROR',
message: 'Something went wrong.',
error: err.message
};
res.status(err.status || 500).send(errorObj);
});

module.exports = app;

编辑 3

For those who don't understand my problem. Explaining the problem in simple words:

  1. 我的 Express 服务器在端口 3000 上运行。
  2. 为了使用来自服务器的任何 API,用户必须登录。
  3. 当用户从 localhost:3000 登录时,服务器会检查凭据(使用 Passport-local)并在响应 header 中返回一个 token 。
  4. 现在登录后,当用户从 localhost:3000 访问任何 API 时,一个预定义的 Header 带有 passport-session,然后是 passport使用 req.isAuthenticated() 验证用户 session ,所有事情都按预期工作。
  5. 当用户从 localhost:4000 登录并且服务器在响应 header 中发送 token 时(与 localhost:3000 相同)。
  6. 当成功登录后,用户点击来自 localhost:4000 的任何 API,passport js 函数 req.isAuthenticated() 返回 false
  7. 发生这种情况是因为在跨域中 cookie 不会发送到我们需要将 withCredentials header 设置为 true 的服务器客户端。
  8. 我已将 withCredentials header 设置为 true 但仍在服务器上 req.isAuthenticated() 返回 false.

最佳答案

绕过 CORS/cookie/同域问题的一个可能解决方案是创建代理服务器,它将所有请求从 localhost:3000/api 镜像到 localhost:4000,然后使用 localhost:3000/api 代替 localhost:4000 访问 API。

生产部署的最佳方式是在您的网络服务器 (nginx/apache) 上进行。

您也可以通过 expressrequest 模块在 Node 中执行此操作,或者使用像这样的现成中间件:

https://github.com/villadora/express-http-proxy

使用这个中间件的解决方案非常简单:

var proxy = require('express-http-proxy');
var app = require('express')();

app.use('/api', proxy('localhost:4000'));

关于javascript - 跨域Nodejs认证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47497296/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com