一、Nuxt项目的不同请求流程
Nuxt服务端渲染解决了Vue单页应用SEO的痛点,但是在权限认证上也带来了一些麻烦。Nuxt项目中,用户切换路由时请求页面和在页面中触发ajax请求数据的的路径是不同的。
具体流程如下图:
上图中,前端即浏览器端,服务端即后台服务(比如python或java),后台服务和nuxt服务中间层也是运行在服务器的。
-
- 进入页面时,因为要先访问nuxt服务进行服务端渲染,此时需要nuxt服务向后台服务请求数据。
- 而在页面中触发ajax请求(比如评论等)时,浏览器发出请求时直达后台服务
二、Nuxt身份验证
1. 普通单页应用ajax的身份验证
Web应用的身份验证依赖登录后后端给前端的身份凭证,即常说的token,是一串字符串,后端可以根据该token对访问者进行身份验证。
正常的单页应用中,我们都是前端直接发送ajax请求到后台服务。前端登录获取到token后,可以将token存储到cookie或者localStorage中。不同之处是cookie在浏览器请求时可以自动携带,而存在localStorage则需要使用请求头将token带到后端。
将token存储localStorage中,axios作为请求库,可以这样设置请求token:
export function getToken () {
return localStorage.getItem('token')
}
const beforeRequest = (config) => {
config.headers['token'] = getToken()
return config
}
const instance = axios.create({
baseURL: xxx,
timeout: 60 * 1000,
headers: {}
})
instance.interceptors.request.use(beforeRequest)
2. nuxt身份验证
对于nuxt,服务端渲染需要的数据是nuxt服务发出的,此时是是在服务器环境下,并没有localStorage,无法直接获取到token。
不过我们可以把token存储在浏览器cookie中,这样浏览器发起的页面请求就会自动带上token。nuxt服务收到页面请求时,获取token并缓存下来,在发往后台服务时设置请求头即可。
如何获取token并缓存呢?nuxt中的中间件,访问页面时会先经过中间件的处理。我们创建一个简单的中间件,将cookie缓存下来:
const serverCookieCache = {
cookie: '',
set (value) {
serverCookieCache.cookie = value
}
}
// middleware/cookie.js
export default function ({ req }) {
if (process.server) {
serverCookieCache.set(req.headers.cookie || '')
}
}
这里将cookie缓存一下,然后我们可以写一个服务器环境和浏览器环境通用的获取token接口:
function getCookie (cookie, key) {
if (!cookie) return ''
let cookieList = cookie.split('; ')
let keyInfo = cookieList.reduce((info, cookieItem) => {
let [key, value] = cookieItem.split('=')
info[key] = value
return info
}, {})
return keyInfo[key] || ''
}
export function getToken () {
const cookies = process.server ? serverCookieCache.cookie : document.cookie
return getCookie(cookies, 'token')
}
axios设置一下请求头:
const beforeRequest = (config) => {
let token = getToken()
config.headers['token'] = token
return config
}
const instance = axios.create({
baseURL: `xxx`,
timeout: 60 * 1000,
})
instance.interceptors.request.use(beforeRequest)
至此,从浏览器和nuxt服务发出的请求,通过同一套axios代码向后台请求数据,都实现了带token进行身份验证。