Nuxt与Node.js在生产环境中的集成实践:Token验证与代理方案

作者:星河时间:2026-10-22 16:35:55浏览:636

本文详细解析Nuxt与Node.js在生产环境中的集成方案。通过Express构建后端服务,结合Session机制解决多用户Token验证问题,并利用中间件代理处理静态资源与API请求。重点阐述如何整合Nuxt渲染逻辑,确保服务端渲染(SSR)与业务接口的有序执行,提供完整的架构思路与代码示例。

上周,甲方要求在应用中开展一项促活活动,具体形式为用户领取OFO骑行券。鉴于此前已在另一款应用中实现了客户端Token验证,我决定直接在现有的Node.js服务基础上进行开发。

技术栈选型:Nuxt与Express

Nuxt

Nuxt类似于React生态中的Next.js,是Vue服务端渲染(SSR)的便捷框架。其目录结构与Vue-Cli相似,但结构更为清晰,且提供了丰富的配置选项,如顶部Loading条、Layer主题模板、利于SEO的服务端渲染以及自动生成Router等功能。选择Nuxt主要基于使用习惯及良好的性能表现,此处不再展开细节。

Express

Express是一款封装了众多便捷方法的Node.js服务端工具,类似于Koa或Egg框架。此处不再赘述其基础用法。

前端页面与业务流程实现

第一步 完成静态页面

此处省略HTML构建及Vue基础使用等无关细节。页面最终效果如图所示:

技术栈选型:Nuxt与Express 

用户点击确认领取后,前端向后端发送请求以获取券码:

技术栈选型:Nuxt与Express 

整体业务流程大致如上所述。

基于Webview的Token验证机制

第二步 基于Webview完成Token验证

甲方如何将Token提供给用户?

  1. 用户登录客户端。
  2. 用户在Webview中访问指定地址。
  3. 客户端将Token等信息绑定在URL上发送给服务端,并向服务端发起GET请求。
  4. 服务端接收到Token后,验证用户身份并返回页面给用户。

因此,当前的Node服务需要完成Token验证功能,具体实现如下:

此处需特别说明Session机制。初期完成Token验证时,发现多用户同时访问会导致后访问者重新执行请求中的方法,造成数据初始化甚至重复赋值,无法区分用户。咨询Java同事后得知,其框架默认处理了Session隔离,这让我感到困惑。实际上,他们虽熟悉Session,但长期使用框架后往往忽略了其存在。

起初我考虑使用Cookie验证浏览器,但认为该方法较为古老且存储容量有限。经过一天探索,发现Session机制可用于验证对应浏览器(本质是将Cookie作为数据索引)。明确这一点后,思路豁然开朗。


// 引入一些工具
const http = require('http')
const express = require("express");
const session = require('express-session');

const nuxtapp = express(); // 创建一个express应用

// 设置SESSION配置
nuxtapp.use(session({
 secret: 'key' // 建议使用 128 个字符的随机字符串 
}));

// 处理OPTIONS请求(axios发送POST请求时会先发送一个OPTION请求验证服务器的连通情况)
nuxtapp.use(function (req, res, next) {
 if ('OPTIONS' === req.method) {
  res.sendStatus(200);
 } else {
  next();
 }
});

// 写一个验证Token的接口
nuxtapp.get('/getphone', (req, res) => {
  if (!req.query.token) {
   // if else ...
   res.sendStatus(200)
   return;
  }
  // 这里创建请求只是举一个例子,有的Token可以本地解析,有的需要服务端向另一个服务端请求解析。(参考微信)
  const request = http.request({
   host: "api.example.com",
   headers: {
    'Content-Type': ' application/json',
    'Accept-Encoding': 'utf-8', //这里设置返回的编码方式 设置其他的会是乱码
    'Accept-Language': 'zh-CN,zh;q=0.8',
    'Connection': 'keep-alive',
   },
   path: '/getTokenorSth',
   port: 'port',
   method: 'POST'
  }, response => {
   let data = ""; // 创建变量记录数据
   response.on("data", function (chunk) {
    data += chunk
   })
   response.on("end", function () { // 设置seesion
    try {
     if (!req.session.id) {
      // set session like : req.session.id= JSON.parse(data)
     }
     res.sendStatus(200)
    } catch (err) {
     console.log(err);
     res.sendStatus(500)
    }
   })
  }).on('error', (e) => {
   console.log(`错误信息: ${e.message}`);
   res.sendStatus(500)
  });
  // POST Data
  request.write(JSON.stringify({
    example:example,
    token: req.query.token
  })); // 用户传过来的数据 post
  request.end();
})

nuxtapp.listen(port || 80, '0.0.0.0')
console.log("已开启服务器,请访问 —— localhost:" + port || 80)

服务端代理与接口处理

第三步 服务端代理(此处存疑:淘宝Node+Java架构是否采用此模式?)

作为前端开发者,功能实现部分交由资深Java工程师处理(若有时间,我也愿编写SQL以复习相关知识)。

用户访问时仍向Node发起请求。需注意的是,若后端提供多个接口,无需为每个接口单独编写app.get('/api')。Express文档中提及了类似以下写法:


nuxtapp.all(["/api1/*","/api2/*"], requestFunction)

其余逻辑与上述Token验证部分相似。

Express集成Nuxt渲染逻辑

第四步 用Express执行Nuxt

Nuxt官网虽有部分代码指导如何使用Node运行Nuxt,但内容尚不完善。在此补充我的理解,如有不当之处,欢迎指正。


// nuxt
const {
 Nuxt,
 Builder
} = require('nuxt') // 引入核心构建属性

// 判断开发环境
const isProd = (process.env.NODE_ENV === 'production')
const port = process.env.PORT || 80

// 引入nuxt配置
const config = require('./nuxt.config.js')
config.dev = !isProd;
const nuxt = new Nuxt(config);

// 判断生产模式 dev(开发者模式)表示重新构建 ;pro(生产模式)表示直接从yanr build的文件直接执行
if (config.dev) {
 new Builder(nuxt).build()
  .then(listen)
  .catch((error) => {
   console.error(error)
   process.exit(1)
  })
} else {
 listen()
}

上述listen函数对应第二、三步中编写的Express服务器接口。

此时Nuxt尚未在代码中直接执行。创建Nuxt实例后返回的nuxt方法,实际上是依据request和response执行相应渲染。需特别注意Express中各种接口的执行顺序:若提前匹配到第二步的GET请求,则后续all方法中的接口将无法被接收。

我的考量是:接口并非无故执行,但用户请求必然发生。因此,除故意发送的请求外,其余请求均由Nuxt接管。故将Nuxt置于最后,负责渲染页面并交付用户。为方便Token验证,我将验证Token的请求置于首页,使浏览器捕获Token及相关信息后交由Node执行手动登录(也可在Nuxt渲染前判断是否存在Token来决定是否进行验证,此处不再展示大量代码)。

结合上述思路,即在最后捕获所有GET请求并交由Nuxt处理:


// 最后捕获nuxt渲染
nuxtapp.get('/*', (req, res) => {
 nuxt.render(req, res)
})

Demo:jasontan.cn

以上为本文全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章
相关文章
更多