JWT认证

作者: TerdShow | 来源:发表于2019-10-03 01:29 被阅读0次

一.什么是jwt?

  • JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案
    解决问题:session不支持分布式架构,无法支持横向扩展,只能通过数据库来保存会话数据实现共享。如果持久层失败会出现认证失败。
    优点:服务器不保存任何会话数据,即服务器变为无状态,使其更容易扩展。

JWT包含了使用.分隔的三部分

  • Header 头部
{ "alg": "HS256", "typ": "JWT"}   
// algorithm => HMAC SHA256
// type => JWT
  • Payload 负载、载荷
JWT 规定了7个官方字段
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
  • Signature 签名
    对前两部分的签名,防止数据篡改
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。Base64 有三个字符+/=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-/替换成_ 。这就是 Base64URL 算法。

使用方式

HTTP 请求的头信息Authorization字段里面

Authorization: Bearer <token>

通过url传输

http://www.xxx.com/pwa?token=xxxxx

如果是post请求也可以放在请求体中

二.服务端返回TOKEN

let express = require('express');
let app = express();
let bodyParser = require('body-parser');
let jwt = require('jsonwebtoken');
app.use((req,res,next)=>{
    res.header("Access-Control-Allow-Origin", "http://localhost:8080");
    res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
    if(req.method.toLowerCase() === 'options'){
        return res.end();
    }
    next();
})
app.use(bodyParser.json());
let secret = 'zfjg';
app.get('/test',(req,res)=>{
    res.end({test:'test'})
})
app.post('/login',(req,res)=>{
   let {username} = req.body;
   if(username === 'admin'){ // 如果访问的是admin 种植cookie
        res.json({
            code:0,
            username:'admin',
            token:jwt.sign({username:'admin'},secret,{
                expiresIn:20  
            })
        })
   }else{
       res.json({
           code:1,
           data:'用户名不存在'
       })
   }
});
app.get('/validate',(req,res)=>{
    let token = req.headers.authorization;
    jwt.verify(token,secret,(err,decode)=>{ // 验证token的可靠性
        if(err){
            return res.json({
                code:1,
                data:'token失效了'
            })
        }else{
            res.json({ 
                username:decode.username,
                code:0, // 延长tokne的过期时间
                token:jwt.sign({username:'admin'},secret,{
                    expiresIn:20  
                })
            })
        }
    });
});

app.listen(3000);

三.路由配置

  • Home.vue 首页
  • Profile.vue 个人中心
  • Login.vue 登录页面
export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home,
    },
    {
      path: '/profile',
      name: 'profile',
      component: Profile,
      meta: { needLogin: true }, // 必须要登录才能访问
    },
    {
      path: '/login',
      name: 'login',
      component: Login,
    },
  ],
});

四.axios封装

import axios from 'axios';
class FetchData {
  constructor() {
    this.baseURL = process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : '/'; // 请求路径 
    this.timeout = 3000; // 设置超时时间
  }

  setInterceptor(instance) { // 设置拦截器
    instance.interceptors.request.use(config => {
      config.headers.Authorization = `${localStorage.getItem('token')}`;
      return config; // 增加token
    }, (err) => {
      Promise.reject(err);
    });

    instance.interceptors.response.use(res => res.data, (err) => {
      Promise.reject(err);
    });
  }

 request(request) {
    const instance = axios.create();
    const config = {
      baseURL: this.baseURL,
      timeout: this.timeout,
      ...request,
    }; // 合并配置
    this.setInterceptor(instance);
    return instance(config);
  }
}

export default new FetchData();

五.测试接口

export const getTest = () => fetchData.request({ url: '/test' });
export const login = username => fetchData.request({
  url: '/login',
  method: 'POST',
  data: {
    username,
  },
});
export const validate = () => fetchData.request({ url: '/validate' });

六.在vuex中发送请求

export default new Vuex.Store({
  state: {
    username: '',
  },
  mutations: {
    setUsername(state, username) {
      state.username = username;
    },
  },
  actions: {
    async login({ commit }, username) {
      const r = await login(username); // 登录成功后返回用户名信息
      if (r.token) { // 如果有返回token说明成功
        commit('setUsername', username); // 将用户存入state中
        localStorage.setItem('token', r.token); // 将token存放起来
      } else { // 否则返回失败的promise
        return Promise.reject(r);
      }
    },
  },
});

七.权限认证

async validate({ commit }) {
    const r = await validate();
    if (r.code === 1) {
        return false;
    }
    commit('setUsername', r.username);
    localStorage.setItem('token', r.token); // 将token存放起来
    return true;
}

判断用户访问权限

router.beforeEach(async (to, from, next) => {
  // 如果不需要校验可以设置白名单
  const isLogin = await store.dispatch('validate');
  if (isLogin) {
    // 如果是登录
    if (to.name === 'login') {
      next('/profile');
    } else {
      next();
    }
  } else {
    const flag = to.matched.some(item => item.meta.needLogin);
    if (flag) {
      next('/login');
    } else {
      next();
    }
  }
});

相关文章

  • JWT认证原理分析

    基于session的认证 JWT认证规则 JWT(Json Web Token) JWT原理 签发算法 校验算法 ...

  • .NET Core5.0 JWT鉴权SSO单点登录

    JWT JWT全称“JSON Web Token”,是基于JSON的用户身份认证的令牌。可跨域身份认证,所以JWT...

  • 带你了解JWT

    @TOC 什么是JWT 认证方式 在JWT之前,我们用过Sssion来进行认证,也使用过Token认证。那么这两种...

  • JWT认证在Django中的简单实现

    安装配置 安装 配置在设置文件REST_FRAMEWORK项中添加jwt认证: 添加JWT认证选项: 后端接口、视...

  • JWT(JSON Web Token)认证机制

    JWT 是JSON Web Token的缩写。我们用大写的JWT表示这种认证机制,我们用小写的jwt来表示JWT机...

  • JWT入门 笔记

    JWT 定义 JWT 其全称为:JSON Web Token,JWT是一个“认证规范”。 简单地说就是 JSON ...

  • JWT Authentication in Django

    Django中的JWT认证 本教程将介绍JSONWeb令牌(JWT)以及如何在Django中实现JWT身份验证。 ...

  • JWT

    JWT | 简介 全称:JSON Web Token; JWT 主要用于身份认证和信息加密; JWT 是一个简单而...

  • jwt介绍,以及在node和koa中的应用

    JWT JSON Web Token( JWT)是目前最流行的跨域认证解决方案。 一般的跨域认证方式 流程如下: ...

  • SpringBoot系列之前后端接口安全技术JWT

    @TOC 1. 什么是JWT? JWT的全称为Json Web Token (JWT),是目前最流行的跨域认证解决...

网友评论

      本文标题:JWT认证

      本文链接:https://www.haomeiwen.com/subject/wpchyctx.html