用户进入网站首次登录,前端会携带用户信息(用户名、密码什么的)到服务端做请求

1、服务端验证用户名密码

        未通过校验:响应给前端,用户名/密码错误等信息

        通过校验:对该用户创建token,并将token作为响应数据返回给前端

2、前端拿到响应数据:

        错误信息:页面给予提示:用户名/密码错误

        正常信息:页面进行跳转进入首页,保存token (可以保存在cookie或localstorage) 

3、用户点击触发请求:

        【路由守卫】(全局——Vue中的 beforeEach())

                判断即将进入的页面需不需要token(例如:路由配置中 meta{authRequired:true})

                        不需要:next()放行,展示页面

                        需要:从本地获取token(获取到则发起请求,没获取到则返回登录页引导登录)

router.beforeEach((to, from, next) => {
  const token = localStorage.getItem('token')
  // 目标路由不是登录页,并且还需要token验证,还没有token,那就直接给返回到登录页
  if (to.name !== 'Login'&& to.meta.authRequired && !token){
      next({ name: 'Login' })
  }else{
      // 目标路由是登录页-自然不需要token验证
      // 或目标路由不需要身份验证
      // 又或目标路由非登录页,需要token验证,但是有token
      // next放行
      next()
  }
})

        存在token,向服务器发起请求时,需要携带token

                避免代码冗余,每次请求都要配置token到请求头中,所以适用【请求拦截器】

const request = axios.create({
  baseURL: 'http://localhost:3000',
  timeout: 5000,
})
// 请求拦截器存在两个函数参数,分别是允许请求发送,不允许请求发送
request.interceptors.request.use(
   // config 就是请求对象
  (config) => {
    const token = localStorage.getItem('token')
    // 将token添加到请求对象的请求头中,跟随请求一并发送至服务器
    if (token) config.headers.Authorization = `Bearer ${token}`;
    // 请求拦截器,允许请求发送的话别忘了给请求对象返回出去,否则请求发不出去
    return config
  },
  (error) => Promise.reject(error),
)

4、服务端校验token

        token这个东西呢,是由服务端生成的,但是不由服务端保存,那咋校验?

        是通过某种算法,配置密钥对用户信息进行加密

        服务端拿到token后会使用密钥再对其进行解密,解密出用户信息

        token校验有效:通过,根据请求信息给予响应数据

        token校验无效:(比如存到了localstorage中,被懂些技术的用户修改了;或token过期了)

                无论怎样都是无效,服务端解密不出来,所以给予前端响应(譬如响应状态码401)

5、前端处理服务端给予的响应

        为了在服务端响应后,在页面展示前对响应做出处理,使用【响应拦截器】

        当状态码时401就说明token校验失败,给予用户提示/跳转到登录页面

        token通过了校验,前端根据响应数据做出展示

// 这里我们假设通过后端响应的数据中的success值判断响应是否成功
request.interceptors.response.use(
  (response) => {     
      const { status, data,message } = response    
      if(data.success){
           // 交由.then处理
           return data
      }else{
           // 假设后端返回状态码401代表token失效,切换到登录页面
           if (status === 401) {
                router.push({ name: 'Login' })
           }
           // 将错误信息通过Promise返回,
           return Promise.reject(message )
      }
  },
  error=>{
      return Promise.reject(error)
  }
)

请求/响应拦截器干啥呢?相同的请求/响应处理放到拦截器里,避免冗余;不同的各自处理。

由于token由后端生成,所以前端只能验证有没有token,不能验证其有效性

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐