What is the 'next' function in Express middleware and how can it help redirect to another function?

huangapple go评论74阅读模式
英文:

What is the 'next' function in Express middleware and how can it help redirect to another function?

问题

我是新手使用Node.js并在Express.js上工作,目前我正在处理特定路由的"中间件函数",我想知道"next"的用途,也就是在身份验证后,"next"函数能做什么?如果我们想要移动/重定向到另一个函数,该如何实现?还有"checkAuthentication"是什么?以下是我的当前代码:

const express = require('express');
const app = express();

// 自定义中间件函数
const authMiddleware = (req, res, next) => {
  // 检查用户是否经过身份验证
  const isAuthenticated = checkAuthentication(req);
  
  if (isAuthenticated) {
    next();
  } else {
    // 用户未经身份验证,发送未授权的响应
    res.status(401).send('未授权');
  }
};

// 中间件函数应用于特定路由
app.get('/protected', authMiddleware, (req, res) => {
  res.send('受保护的路由');
});

// 路由处理程序
app.get('/', (req, res) => {
  res.send('主页');
});

// 启动服务器
app.listen(3000, () => {
  console.log('服务器正在监听端口3000');
});

请注意,"checkAuthentication"函数应该在代码中定义以进行身份验证检查。

英文:

I am new in Nodejs and working on Express js, Right now i am working on "middleware function" for specific routes,I want to know that "what is use of next",means after autheticate what "next" function can do ? if we want to move/redirect to another function then how we can do ? And what is "checkAuthentication" ? Here is my current code

const express = require('express');
const app = express();

// Custom middleware function
const authMiddleware = (req, res, next) => {
  // Check if user is authenticated
  const isAuthenticated = checkAuthentication(req);
  
  if (isAuthenticated) {
    next();
  } else {
    // User is not authenticated, send an unauthorized response
    res.status(401).send('Unauthorized');
  }
};

// Middleware function is applied to specific routes
app.get('/protected', authMiddleware, (req, res) => {
  res.send('Protected Route');
});

// Route handler
app.get('/', (req, res) => {
  res.send('Home Page');
});

// Start the server
app.listen(3000, () => {
  console.log('Server is listening on port 3000');
});


答案1

得分: 1

下面是传递给中间件函数的回调函数。在不同的框架中,它可能有不同的名称,但概念是相同的。

我将尝试通过你的代码来解释中间件。

const express = require('express');
const app = express();

function checkAuthentication(req) {
  /*
  我将这个函数视为我的身份验证函数。
  当用户登录时,服务器会向他发送一个令牌,现在这个令牌将充当验证器。
  */

  if (req.headers.token) {
    const user = someFunctionToFetchUser(req.header.token);
    return user;
  } else {
    return false;
  }
}

/*
现在我想在每个受保护的 API 路由上有一个函数,
以确保用户只有在有有效令牌的情况下才能与数据库交互,否则抛出错误
*/

const authMiddleware = (req, res, next) => {
  // 检查用户是否已认证
  const isAuthenticated = checkAuthentication(req);

  if (isAuthenticated) {
    // 现在您已经验证了令牌的有效性。所以允许用户
    // 访问控制器或其他中间件(如果有的话)。
    next();
  } else {
    // 用户未经认证,发送未经授权的响应
    res.status(401).send('Unauthorized');
  }
};

// 中间件函数应用于特定路由
app.get('/protected', authMiddleware, (req, res) => {
  res.send('Protected Route');
});

// 您可以拥有任意数量的中间件
app.get('/protected', authMiddleware, someOtherMiddleware, (req, res) => {
  res.send('Protected Route');
});

// 还可以通过将其附加到请求中将数据从中间件传递给下一个中间件/控制器

function newMiddleware(req, res, next) {
  req.foo = "bar"; //现在您可以在下一个函数中访问此 foo 变量。
}

如果您需要更多帮助,请告诉我。

英文:

Next is a callback function that is passed to a middleware function. You can find different names of it in different frameworks but, the concept remains the same.

I'll try to explain the middleware through your code itself.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const express = require(&#39;express&#39;);
const app = express();

function checkAuthentication(req) {
  /*
  I am considering this as my authentication function. 
  When the user logged in, server has sent him a token, which now will act as a validator. 
  */

  if (req.headers.token) {
    const user = someFunctionToFetchUser(req.header.token)
    return user
  } else {
    return false
  }
}

/*
Now I want a function to be there on each protected api routes
to make user if user has a valid token then only allow them to interact with the data base otherwise throw an error 
*/


const authMiddleware = (req, res, next) =&gt; {
  // Check if user is authenticated
  const isAuthenticated = checkAuthentication(req);

  if (isAuthenticated) {
    // Now you have verified the has valid a token. So allow user 
    // to reach to the controller or any other middleware, if any.
    next();
  } else {
    // User is not authenticated, send an unauthorized response
    res.status(401).send(&#39;Unauthorized&#39;);
  }
};

// Middleware function is applied to specific routes
app.get(&#39;/protected&#39;, authMiddleware, (req, res) =&gt; {
  res.send(&#39;Protected Route&#39;);
});

// You can have any number of middlewares
app.get(&#39;/protected&#39;, authMiddleware, someOtherMiddleware, (req, res) =&gt; {
  res.send(&#39;Protected Route&#39;);
});

// And also you can pass data from middleware to next middleware/controller also by attahching it with request

function newMiddleware(req, res, next) {
  req.foo = &quot;bar&quot; //Now you can access this foo variable in next function.
}

<!-- end snippet -->

答案2

得分: 0

  1. 你可以发送响应给请求并完成该请求的路由。发送响应后,不要调用 next()。在你的示例中,在 if (isAuthenticated) 的 else 分支中,执行 res.status(401).send('Unauthorized'); 就是这样的情况。它发送了响应而没有调用 next()

  2. 你可以通过调用 next(err) 并传递一个错误对象来将 Express 传递给其错误处理程序。这将终止进一步的路由,控制流将移动到为 Express 安装的任何错误处理程序。

  3. 你可以告诉 Express 你想继续路由到其他可能匹配此请求的路由处理程序。这是通过调用 next() 而不向 next 传递任何参数来实现的。在你的代码示例中,在 if (isAuthenticated) 分支中调用 next() 就是这样的情况。

总结 - 因此,调用 next() 且不传递参数,将继续路由到与当前路由匹配的其他请求处理程序。调用 next(err) 将控制传递给 Express 错误处理程序。

对于你的其他问题:

> 如果我们想要移动/重定向到另一个函数,我们应该如何做?

这里不太清楚你具体是什么意思。next() 只是继续路由。它不会调用特定的函数。如果你想调用特定的函数,可以在你的中间件中直接进行函数调用。

如果你想将客户端重定向到新的 URL,可以使用 res.redirect(someURL) 发送响应,而不要调用 next()

> "checkAuthentication" 是什么?

由于你没有透露该代码,我们无法确定它的具体作用。我猜想它可能会检查 cookie 或标头中的某些内容,以查看客户端是否已经通过身份验证,或者是否在此请求中包含了凭据。

英文:

When you are writing a middleware handler, you have several choices at the end of whatever you are doing.

  1. You can send a response to the request and finish the routing for that request. You send a response and do NOT call next(). In your example, that's what happens in the else branch of your if (isAuthentcated) that does res.status(401).send(&#39;Unauthorized&#39;);. It sends a response without calling next().

  2. You can send Express to its error handler by calling next(err) where you pass next an error object. This will terminate further routing and control flow will move to whatever error handler is installed for Express.

  3. You can tell Express that you want to continue routing to other route handlers that may also match this request. You do that by calling next() not passing any arguments to next. In your code example, this is what happens in the if (isAuthentcated) branch where it calls next().

Summary - So, calling next() with no arguments, continue routing to other request handlers that match the current route. Calling next(err) passes control the the Express error handler.

For your other questions:

> if we want to move/redirect to another function then how we can do ?

It's not clear what exactly you mean here. next() just continues routing. It doesn't call a specific function. If you want to call a specific function, you can just do so with a function call in your middleware.

If you want to redirect the client to a new URL, you can send a response with res.redirect(someURL) and not call next().

> And what is "checkAuthentication" ?

Since you don't disclose the code for that, we don't know for sure what it does. I would guess that it's checking something in a cookie or a header to see if the client appears to already be authenticated or if credentials were included with this request.

答案3

得分: 0

我希望这能帮助你更好地理解它。

const express = require('express');
const app = express();
const port = 3000;
const path = require('path');

function firstMiddleware(req, res, next) {
  console.log('You are in first middleware');
  req.firstMiddleware = true;
  next(); // I am deliberately asking to pass the control to the next immediate function
}

function secondMiddleware(req, res, next) {
  console.log('You are in second middleware');
  req.secondMiddleware = true;
  next(); // same here, sending control to next immediate function
}

app.get('/', firstMiddleware, secondMiddleware, function(req, res) {
  console.log('Now I am in a controller');
  console.log(
    `Checking if the control was in firstMiddleware ${req.firstMiddleware}`
  );
  console.log(
    `Checking if the control was in secondMiddleware ${req.secondMiddleware}`
  );
  // here i do not have next paramater, this is what makes it different from a middleware.
  // So if next is not there then you need to send the control back to frontend when everything is done
  res.status(200).send('API worked');
});
app.listen(port, () => {
  // Code.....
})
英文:

I hope this helps you to understand it better.
<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const express = require(&#39;express&#39;);
const app = express();
const port = 3000;
const path = require(&#39;path&#39;);

function firstMiddleware(req, res, next) {
  console.log(&#39;You are in first middleware&#39;);
  req.firstMiddleware = true;
  next(); // I am deliberately asking to pass the control to the next immediate function
}

function secondMiddleware(req, res, next) {
  console.log(&#39;You are in second middleware&#39;);
  req.secondMiddleware = true;
  next(); // same here, sending control to next immediate function
}


app.get(&#39;/&#39;, firstMiddleware, secondMiddleware, function(req, res) {
  console.log(&#39;Now I am in a controller&#39;);
  console.log(
    `Checking if the control was in firstMiddleware ${req.firstMiddleware}`
  );
  console.log(
    `Checking if the control was in secondMiddleware ${req.secondMiddleware}`
  );
  //here i do not have next paramater, this is what makes it different from a middleware. 
  //So if next is not there then you need to send the control back to frontend when everything is done
  res.status(200).send(&#39;API worked&#39;);
});
app.listen(port, () =&gt; {
  // Code.....
})

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年5月25日 01:50:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76326217.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定