另外, @nuxtjs/dotenv 允许打包时指定其他的env文件。比如,开发时我们使用的是 .env ,但我们打包的线上版本想用其他的环境变量,此时可以指定build时用另一份文件如 /.env.prod ,只需在 nuxt.config.js 指定:
module.exports = { modules: [ ['@nuxtjs/dotenv', { filename: '.env.prod' }] // 指定打包时使用的dotenv ], }
@nuxtjs/toast模块
toast可以说是很常用的功能,一般的UI框架都会有这个功能。但如果你的站点没有使用UI框架,而alert又太丑,不妨引入该模块:
npm install @nuxtjs/toast
然后在 nuxt.config.js 中引入
module.exports = { modules: [ '@nuxtjs/toast', ['@nuxtjs/dotenv', { filename: '.env.prod' }] // 指定打包时使用的dotenv ], toast: {// toast模块的配置 position: 'top-center', duration: 2000 } }
这样,nuxt就会在全局注册 $toast 方法供你使用,非常方便:
this.$toast.error('服务器开小差啦~~') this.$toast.error('请求成功~~')
API鉴权
对于某些敏感的服务,我们可能需要对API进行鉴权,防止被人轻易盗用我们node端的API,因此我们需要做一个API的鉴权机制。常见的方案有jwt,可以参考一下阮老师的介绍: 《JSON Web Token 入门教程》 。如果场景比较简单,可以自行设计一下,这里提供一个思路:
客户端和node端在环境变量中声明一个秘钥:SECRET=xxxx,注意这个是保密的;
客户端发起请求时,将当前时间戳(timestamp)和 SECRET 通过某种算法,生成一个 signature ,请求时带上 timestamp 和 signature ;
node接收到请求,获得 timestamp 和 signature ,将 timestamp 和秘钥用同样的算法再生成一次签名 _signature
对比客户端请求的 signature 和node用同样的算法生成的 _signature ,如果一致就表示通过,否则鉴权失败。
具体的步骤:
客户端对axios进行一层封装:
import axios from 'axios' import sha256 from 'crypto-js/sha256' import Base64 from 'crypto-js/enc-base64' // 加密算法,需安装crypto-js function crypto (str) { const _sign = sha256(str) return encodeURIComponent(Base64.stringify(_sign)) } const SECRET = process.env.SECRET const options = { headers: { 'X-Requested-With': 'XMLHttpRequest' }, timeout: 30000, baseURL: '/api' } // The server-side needs a full url to works if (process.server) { options.baseURL = `${process.env.HOST || 'localhost'}:${process.env.PORT || 3000}/api` options.withCredentials = true } const instance = axios.create(options) // 对axios的每一个请求都做一个处理,携带上签名和timestamp instance.interceptors.request.use( config => { const timestamp = new Date().getTime() const param = `timestamp=${timestamp}&secret=${SECRET}` const sign = crypto(param) config.params = Object.assign({}, config.params, { timestamp, sign }) return config } ) export default instance
接着,在server端写一个鉴权的中间件, /server/middleware/verify.js :
const sha256 = require('crypto-js/sha256') const Base64 = require('crypto-js/enc-base64') function crypto (str) { const _sign = sha256(str) return encodeURIComponent(Base64.stringify(_sign)) } // 使用和客户端相同的一个秘钥 const SECRET = process.env.SECRET function verifyMiddleware (req, res, next) { const { sign, timestamp } = req.query // 加密算法与请求时的一致 const _sign = crypto(`timestamp=${timestamp}&secret=${SECRET}`) if (_sign === sign) { next() } else { res.status(401).send({ message: 'invalid token' }) } } module.exports = { verifyMiddleware }
最后,在需要鉴权的路由中引用这个中间件, /server/index.js :
const { Router } = require('express') const { verifyMiddleware } = require('../middleware/verify.js') const router = Router() // 在需要鉴权的路由加上 router.get('/test', verifyMiddleware, function (req, res, next) { res.json({name: 'test'}) })
静态文件的处理
根目录下有个 /static 文件夹,我们希望这里面的文件可以直接通过url访问,需要在 /server/index.js 中加入一句:
const express = require('express') const app = express() app.use('/static', express.static('static'))
四、Nuxt开发相关 生命周期
Nuxt扩展了Vue的生命周期,大概如下: