Интерфейсная архитектура интерфейса vue+axios реализует перехват входа в систему (перехват маршрутизации, перехват http)

Архитектура внешний интерфейс Vue.js axios
Интерфейсная архитектура интерфейса vue+axios реализует перехват входа в систему (перехват маршрутизации, перехват http)

Предисловие:

Я написал JWT-аутентификацию узла ранее.Чтобы соответствовать узлу и выполнить весь процесс, внешний интерфейс настроит перехват входа в систему, а именно перехват маршрута и перехват http. Посмотреть больше документовгитхаб-адрес

Соответствует серверу узла:JWT-аутентификация узла интерфейсной архитектуры

Грубый процесс:При выполнении маршрутных переходов используйтеvue-routerпредусмотрена функция хукаbeforeEach()Судя по маршруту, если он соответствует условиям next(), если нет, то он перейдет на страницу входа. При отправке запросов обрабатывать все http-запросы и ответы единообразно, использовать перехватчик axios и настраиватьhttp resquest interceptorsДобавьте поле Authorization в заголовок http, содержимое которого Token, через конфигурациюhttp response interceptorsОбработайте возвращенные данные.

Структура каталога:

Соберите проект с помощью vue-cli,vue init webpack name

Давайте поговорим о файлах src, ресурсы размещают статические файлы, компоненты размещают некоторые общедоступные компоненты, страницы размещают некоторые основные страницы, а маршрутизатор настраивает файлы маршрутизации.

Настройте proxyTable в config> index.js

proxyTable: {
  '/api': { // '/api':匹配项
    target: 'http://127.0.0.1:3000/',//设置你调用的接口域名和端口号 别忘了加http
    changeOrigin: true,
    pathRewrite: {
      '^/api': ''//这里理解成用‘/api’代替target里面的地址,后面组件中我们掉接口时直接用api代替 比如我要调用'http://127.0.0.1:3000/user/add',直接写‘/api/user/add’即可
    }
  }
},

перехват маршрута

Настройте beforeEach в router> index.js

//路由跳转之前
router.beforeEach((to, from, next) => {
  if (to.path !== '/login' && !localStorage.token) {
    return next('/login')
  }
   next()
})

Каждый метод ловушки получает три параметра:
* to: Route: Целевой объект маршрута, который собирается войти
* from: Route: Маршрут, по которому уходит текущая навигация
* next: Функция: Обязательно вызовите этот метод, чтобы разрешить этот хук. Эффект выполнения зависит от параметров вызова следующего метода.
* next(): Сделать следующий хук в конвейере. Если все хуки выполнены, то состояние навигации подтверждается (confirmed).
* next(false): прервать текущую навигацию. Если URL-адрес браузера изменится (либо вручную пользователем, либо с помощью кнопки «Назад» в браузере), тогда URL-адрес будет сброшен на адрес, соответствующий исходному маршруту.
* next('/') or next({ path: '/' }): переход к другому адресу. Текущая навигация прерывается и создается новая.

Обязательно вызовите следующий метод, иначе ловушка не будет разрешена.

Этот метод представляет собой простое внешнее управление маршрутизацией и не может помешать пользователям получить доступ к маршрутам, для которых требуются разрешения на вход. Есть и другая ситуация: текущий токен недействителен, но токен все еще хранится локально. На этом этапе, когда вы переходите на маршрут, требующий разрешений на вход в систему, вы должны попросить пользователя снова войти в систему.
В настоящее время вам необходимо объединить перехватчик http + код состояния http, возвращаемый внутренним интерфейсом, чтобы судить.

перехватчик

Чтобы создать новый http.js для настройки перехватчика axios, для единообразной обработки всех http-запросов и ответов, вы должны использовать перехватчик axios. по конфигурацииhttp resquest interceptorsДобавьте поле Authorization в заголовок http, содержимое которого Token, через конфигурациюhttp response interceptors, когда внутренний интерфейс возвращается401 Unauthorized(未授权), чтобы пользователь снова вошел в систему.

assets>js>http.js

import axios from 'axios'

const http = axios.create()
// http request 拦截器
// 每次请求都为http头增加Authorization字段,其内容为Token
http.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.common['Authorization'] = token;
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// http response 拦截器
http.interceptors.response.use(response => {
  let data = response.data
  if (data.code === 200) {
    return data.data
  }
  if (data.code === 401) {
    window.location.href = '/login'
  }
  return Promise.reject(data)
}, error => {
  return Promise.reject(error)
})

export default http

На этом этапе перехват достигнут, просто установите токен на стороне входа и сохраните его в localStorage.

login.vue

login(){
  console.log(1111)
  this.$http.post('/api/login').then(res => {
      localStorage.setItem('token', res)
      location.replace('/index')
  })
}

Таким образом, может быть реализована аутентификация входа в систему, которая может соответствовать предыдущему фону узла и будет постепенно улучшаться...

Продолжение следует 1...

Я долго не доводил до совершенства этот проект, в основном из-за того, что я не знаю, какой проект должен быть сделан. Если у вас есть идея, вы можете оставить сообщение. Я могу попробовать. В этот раз я улучшил его немного.

Посмотрите на картинку, добавьте интерфейс входа и домашнюю страницу, уродливо уродливо, просто взгляните



Домашняя страница примерно разделена на навигацию слева, верхнюю часть справа, следующий контент и собственный упакованный компонент. Вы можете обратиться к нему. Основная цель — зарегистрировать некоторые компоненты, которые вы инкапсулируете глобально, поэтому вам не нужно ссылаться на него на странице.

содержание



Грубо говоря, страницы ставят страницы, страницы->база ставят левую навигацию, шапку и контент главной страницы, а чены ставят свои инкапсулированные компоненты

router

Немного изменена конфигурация роутера

Vue.use(Router)

// 设置默认路由
let defaultRouter = [

]
// 设置其他角色路由
let routerMap = {

}

// 设置通用路由
let routerArr = [
  {
    path: '/login',
    name: 'login',
    component: login,
  },
  {
    path: '/index',
    component: Layout,
    children: [
      {
        path: '/',
        component: resolve => {
          require(['@/components/home'], resolve)
        }
      },
      {
        path: '/first',
        component: resolve => {
          require(['@/pages/first/first'], resolve)
        }
      },
      {
        path: '/second1',
        component: resolve => {
          require(['@/pages/second/second1'], resolve)
        }
      },
      {
        path: '/second2',
        component: resolve => {
          require(['@/pages/second/second2'], resolve)
        }
      }
    ]
  },
  {path: '/', redirect: 'login'}
]
const router = new Router({
  mode: 'history',
  routes: routerArr
})

все остальное просто

Домашняя планировка

Боковая панель цитат и заголовки

<template>
  <div class="app">
    <side-bar/>
    <section class="main">
      <headers/>
      <section class="page">
        <router-view/>
      </section>
    </section>
  </div>
</template>

упаковать свои собственные компоненты

mian.js 

import ChenUI from './chens'

Vue.use(ChenUI) 

chens->index.js Компоненты траверсы, экспорт

import Chen from './chen/index'
const components = [
  Chen
]
// 遍历组件const install = function (Vue) {
  components.forEach(component => {
    Vue.component(component.name, component)
  })
}
export default install

chen-> index.vue получитьвариант,tools

<template>
<div class="chen-search-pager">
  <section class="search-pager-warp">
    <router-link :to="option.back" class="router-link">
      <i class="el-icon-back"></i>
      <span class="title">{{this.option.title}}</span>
    </router-link>
    <div class="tools-warp" v-if="tools">
        <el-button  v-for="(item, index) in tools" :key="index" @click="btnClick(item)">
          <i :class="iconClass(item)"></i>{{item.label}}
        </el-button>
    </div>
  </section>
</div>
</template>

<script>
  export default {
    name: "chen",
    props: {
      option: {
        type: Object,
        default: () => ({})
      },
      tools: Array
    },
    data () {
      return {

      }
    },
    methods: {
      btnClick (item) {
        item.func && item.func(item)
      },
      iconClass (item) {
        return 'el-icon-' + item.icon
      }
    }
  }
</script>

<style lang="less" scoped>
  .chen-search-pager {
    .search-pager-warp {
      padding: 10px 20px;
      line-height: 40px;
      border-bottom: 2px solid #fff;
      .router-link {
        font-size: 18px;
        i {
          font-size: 15px;
          font-weight: 700;
          color: #cc0b8b;
        }
        .title {
          color: #333;
          font-size: 16px;
          font-weight: 700;
          padding-left: 6px;
        }
      }
      .tools-warp {
        display: inline-block;
        float: right;
        &:after {
          clear: both;
        }
      }
      .el-button {
        border: none;
        background: none;
        color: #cc0b8b;
      }

    }
  }
</style>

настройка опции получает название объекта и обратно

option: {
  title: '没想到吧',
  back: '/first'
},

конфигурация инструментов получает массив

tools: [
  {
    label: '刷新',
    icon: 'reset',
    func: () => { console.log('没想到吧')}
  },
  {
    label: '新增',
    icon: 'plus'
  },
  {
    label: '删除',
    icon: 'delete'
  }
]

На данный момент вы реализовали свой собственный инкапсулированный компонент, который можно вызывать в любом компоненте...

продолжение следует...