Помимо файлов cookie, вы также можете использовать jwt (веб-токен json)!

внешний интерфейс сервер JavaScript Vue.js

1. Познакомьтесь с jwt (веб-токен json)

  • jwt основан наjsonоткрытых стандартов.
  • jwt используется для передачи аутентифицированной идентификационной информации пользователя между поставщиками удостоверений и поставщиками услуг.Проще говоря, это средство проверки личности, например проверка входа в систему, например, файл cookie, который мы использовали ранее.
  • jwt может использовать алгоритм HMAC или пару открытых и закрытых ключей RSA для подписи, чтобы обеспечить надежность информации.

2. Сценарии применения

Например, в сценарии аутентификации, когда пользователь входит в систему, каждый последующий запрос будет содержать jwt для проверки идентификационной информации. Поскольку обе стороны коммуникации используют jwt для кодирования данных, их информация подписывается, поэтому может быть обеспечена безопасность информации.

3. jwt против файлов cookie

Недостатки файлов cookie

  • Клиент отправляет запрос на сервер. После того, как сервер установит файл cookie, каждый запрос будет приносить файл cookie, что приводит к нерациональному использованию полосы пропускания.
  • Доступ к файлам cookie между серверами невозможен, а междоменный доступ не поддерживается.
  • Сервер должен хранить вошедший в систему пользовательский объект, тратя впустую память сервера.

преимущества jwt

  • jwt не зависит от состояния, ему не нужно приносить токен с каждым запросом, экономя трафик
  • Серверу не нужно занимать память, а информация относительно достоверна
  • Может быть разделен между серверами

4. структура jwt

  • Заголовок: {typ:'jwt',alg:'HS256'} alg: Алгоритм, используемый в настоящее время для шифрования; кодировка Base64Url используется для формирования первой части структуры JWT.
  • Полезная нагрузка PlyLoad: место для хранения достоверной информации
  • Подпись подписи: для создания подписи необходимо использовать закодированный заголовок и полезную нагрузку, а также секретный ключ; например, если вы хотите использовать алгоритм HMAC SHA256, подпись должна быть создана следующим образом. HMACSHA256 (base64UrlEncode (заголовок) + "." + base64UrlEncode (полезная нагрузка), секрет)

Выход полного формата jwt представляет собой Base64, закодированный в трех сегментах, разделенных . Секретный ключ хранится на сервере, и сервер сгенерирует токен и проверит его на основе этого ключа, поэтому его необходимо защитить.

5. Возьмите каштан

экспресс+вью+мангуст Серверная часть app.js, включая интерфейсы регистрации, входа и заказа.

let express = require('express')
let bodyParser = require('body-parser')//中间件
let jwt = require('jwt-simple')//jwt库
//数据库
let User = require('./model/user')
//监听函数
let app = express()
let {secret} = require('./config')
//中间件一定是函数,处理发回来的json类型,还有text,urlencoded(a=b&c=d)
app.use(bodyParser.json())

//防止跨域 request请求 response响应
app.use(function(req, res, next){
    res.setHeader('Access-Control-Allow-Origin','*');//简单点,接收所有
    res.setHeader('Access-Control-Allow-Headers','Content-type,Authorization');
    res.setHeader('Access-Control-Allow-Methods','GET,POST,DELETE,PUT,OPTIONS');
    if(req.method === 'OPTIONS') {
        res.end()
    }else {
        next()
    }
})

//注册
app.post('/reg', async function(req, res, next){
    let user = req.body;
    try {
        user = await User.create(user) //在数据库中插入数据
        res.json({
            code: 0,
            data: {
                user: {
                    id: user._id,
                    username: user.username
                }
            }
        })
    } catch (error) {
        res.json({
            code: 1,
            data: '注册失败'
        })
    }  
})
//登录
app.post('/login', async function(req,res,next){
    let user = req.body;
    user = await User.findOne(user)//数据库中查找
    if(user) {
        let token = jwt.encode({//编码
            id: user._id,
            username: user.username
        },secret);
        res.json({//返回信息
            code: 0,
            data: { token }
        })
    }else {
        res.json({
            code: 1,
            data: '用户不存在'
        })
    }
}) 
// 用户校验 中间件
let auth = function(req, res, next){
    //post模拟时 添加Headers Authorization: Bearer token的值
    let authorization = req.headers['authorization']
    if(authorization) {
        let token = authorization.split(' ')[1];
        try {
            //看token是否合法,解码,如果串改过token就解不出来,进入异常页面
            let user = jwt.decode(token, secret);
            req.user = user;//后面就可以拿到user,中间件用法 
            next();//下一步
        } catch (error) {
            console.log(error)
            res.status(401).send('Not Allowed')
        }
    } else {
        res.status(401).send('Not Allowed');
    }
}
//发送请求,看看能不验证成功auth,如果可以拿到返回数据
app.get('/order', auth, function(req,res,next){
    res.json({
        code: 0,
        data: {
            user: req.user
        }
    })
})
app.listen(3000)

страница базы данных

// 操作数据库
let mongoose = require('mongoose');
let {DB_URL} = require('../config');

mongoose.connect(DB_URL,{useNewUrlParser:true})

/**
  * 连接成功
  */
 mongoose.connection.on('connected', function () {    
    console.log('Mongoose connection open to ' + DB_URL);  
});    

/**
 * 连接异常
 */
mongoose.connection.on('error',function (err) {    
    console.log('Mongoose connection error: ' + err);  
});

//创建Schema数据模型
let UsrSchema = new mongoose.Schema({
    username: String,
    password: String
});
module.exports = mongoose.model('User', UsrSchema);

простой пакет аксиом

import axios from 'axios'
import router from '../src/router'
axios.defaults.baseURL = 'http://localhost:3000'
//axios 拦截器对拿到的数据进行拦截
axios.interceptors.response.use(function(res){
    if(res.data.code !== 0) {
        return Promise.reject(res.data.data)
    }
    return res.data;
},res=>{
    if(res.response.status === 401){ // 没权限跳到登录页
        router.history.push('/login');
    }
    return Promise.reject('Not Allowed');
});

//对发送的请求统一加上token,来验证是否是本人登录
axios.interceptors.request.use(function(config){
    let token = localStorage.getItem('token')
    if(token) {
        config.headers.Authorization = `Bearer ${token}`
    }
    return config;
})

export default axios

config.js

module.exports = {
    'DB_URL': 'mongodb://localhost:27017/jwt',
    'secret': 'jeffywin'//秘钥 加盐
}

Внешний интерфейс, леса vue-cli, нечего сказать, интерфейс входа в систему

<template>
  <div class="main">
    <div class="item">
      <div style="width:100px">登录页</div> 
      <input type='text' v-model='user.username'/>
    </div>
    <div class="item">
      <div style="width:100px">密码</div> 
      <input type='text' v-model='user.password'/>
    </div>
    <button @click="login">提交</button>  
  </div>
</template>

<script>
import axios from '../../utils/axios'
export default {
  data() {
      return {
        user: {
          username: '',
          password: ''
        }
      }
  },
  methods: {
    login() {
      axios.post('/login',this.user).then(res => {
        localStorage.setItem('token', res.data.token)//登录后存储token
        this.$router.push('/order')
      })
    }
  }
}
</script>

<style scoped lang="scss">
.main {
  margin: 0 auto;
  width: 300px;

  .item {
    display: flex;
    margin-bottom: 10px;
  }
  }
</style>

интерфейс заказа

<template>
  <div class="order">
    <h1>This is an order page</h1>
    {{username}}//如果登录成功,跳转order界面,拿到登录的用户
  </div>
</template>

<script>
import axios from '../../utils/axios'
  export default {
    data() {
      return {
        username: ''
      }
    },
    mounted() {
      axios.get('/order').then(res => {
        this.username = res.data.user.username
      })
    },
  }
</script>

Исходный код у меня на гитхабеGitHub.com/Джефф Винс/Сегодня вечером…