精华内容
下载资源
问答
  • vue token验证

    2020-08-26 22:30:57
    vue token验证 在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下: 1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码 2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个...

    vue token验证

    在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下:

    1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码
    2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token
    3、前端拿到token,将token存储到localStorage和vuex中,并跳转路由页面
    4、前端每次跳转路由,就判断 localStroage 中有无 token ,没有就跳转到登录页面,有则跳转到对应路由页面
    5、每次调后端接口,都要在请求头中加token
    6、后端判断请求头中有无token,有token,就拿到token并验证token,验证成功就返回数据,验证失败(例如:token过期)就返回401,请求头中没有token也返回401
    7、如果前端拿到状态码为401,就清除token信息并跳转到登录页面
    1234567

    ① 调登录接口成功,在回调函数中将token存储到localStorage和vuex中(login.vue中)

    <template>
      <div>
        <input type="text" v-model="loginForm.username" placeholder="用户名"/>
        <input type="text" v-model="loginForm.password" placeholder="密码"/>
        <button @click="login">登录</button>
      </div>
    </template>
     
    <script>
    import { mapMutations } from 'vuex';
    export default {
      data () {
        return {
          loginForm: {
            username: '',
            password: ''
          },
          userToken: ''
        };
      },
     
      methods: {
        ...mapMutations(['changeLogin']),
        login () {
          let _this = this;
          if (this.loginForm.username === '' || this.loginForm.password === '') {
            alert('账号或密码不能为空');
          } else {
            this.axios({
              method: 'post',
              url: '/user/login',
              data: _this.loginForm
            }).then(res => {
              console.log(res.data);
              _this.userToken = res.data.data.body.token;
              // 将用户token保存到vuex中
              _this.changeLogin({ token: _this.userToken });
              _this.$router.push('/home');
              alert('登陆成功');
            }).catch(error => {
              alert('账号或密码错误');
              console.log(error);
            });
          }
        }
      }
    };
    </script>
    
    

    在这里插入图片描述
    ② store文件夹下的index.js

    import Vue from 'vue';
    import Vuex from 'vuex';
    Vue.use(Vuex);
     
    const store = new Vuex.Store({
     
      state: {
        // 存储token
        token: localStorage.getItem('token') ? localStorage.getItem('token') : ''
      },
     
      mutations: {
        // 修改token,并将token存入localStorage
        changeLogin (state, user) {
          state.token = user.token;
          localStorage.setItem('token', user.token);
        }
      }
    });
     
    export default store;
    
    

    ③ 路由守卫(router文件夹下的index.js)

    import Vue from 'vue';
    import Router from 'vue-router';
    import login from '@/components/login';
    import home from '@/components/home';
     
    Vue.use(Router);
     
    const router = new Router({
      routes: [
        {
          path: '/',
          redirect: '/login'
        },
        {
          path: '/login',
          name: 'login',
          component: login
        },
        {
          path: '/home',
          name: 'home',
          component: home
        }
      ]
    });
    // 导航守卫
    // 使用 router.beforeEach 注册一个全局前置守卫,判断用户是否登陆
    router.beforeEach((to, from, next) => {
      if (to.path === '/login') {
        next();
      } else {
        let token = localStorage.getItem('token');
     
        if (token === null || token === '') {
          next('/login');
        } else {
          next();
        }
      }
    });
     
    export default router;
    
    

    ④ 请求头token

    // 添加请求拦截器,在请求头中加token
    axios.interceptors.request.use(
      config => {
        if (localStorage.getItem('token')) {
          config.headers.token = localStorage.getItem('token');
        }
     
        return config;
      },
      error => {
        return Promise.reject(error);
      });
    

    ⑤ 如果前端拿到状态码为401,就清除token信息并跳转到登录页面

      localStorage.removeItem('token');
      this.$router.push('/login');
    

    流程图:
    在这里插入图片描述

    展开全文
  • 后端使用flask设计基于token认证方式的restful接口,前端使用vue.js全家桶,利用axios通讯。感谢两篇文章的作者:后端FlaskFlask采用token认证方式,主要思路是通过/api/login登录获取token,然后使用token调用各个...

    后端使用flask设计基于token认证方式的restful接口,前端使用vue.js全家桶,利用axios通讯。

    感谢两篇文章的作者:

    后端Flask

    Flask采用token认证方式,主要思路是通过/api/login登录获取token,然后使用token调用各个接口。

    所用到框架的库:

    flask

    flask-cors:flask跨域

    flask-sqlachemy: flask数据库orm

    flask-httpauth:flask的auth认证

    passlib: python密码解析库

    itsdangerous

    后端结构图

    flask/

    ├── app # 主目录

    │   ├── __init__.py

    │   ├── __init__.pyc

    │   ├── models.py # 数据库

    │   ├── models.pyc

    │   ├── views.py # 视图

    │   └── views.pyc

    ├── config.py # 配置信息

    ├── config.pyc

    ├── db_create.py # 创建数据库

    ├── db_migrate.py # 更新数据库

    ├── db_repository

    │   ├── __init__.py

    │   ├── __init__.pyc

    │   ├── manage.py

    │   ├── migrate.cfg

    │   ├── README

    │   └── versions

    │   ├── 008_migration.py

    │   ├── 008_migration.pyc

    │   ├── 009_migration.py

    │   ├── 009_migration.pyc

    │   ├── __init__.py

    │   └── __init__.pyc

    ├── index.html

    └── run.py # app的运行文件

    具体实现

    系统初始化app/__init__.py

    # -*- coding:utf-8 -*-

    from flask import Flask

    from flask_sqlalchemy import SQLAlchemy

    from flask_httpauth import HTTPBasicAuth

    from flask_cors import CORS

    app = Flask(__name__)

    # flask的跨域解决

    CORS(app)

    app.config.from_object('config')

    db = SQLAlchemy(app)

    auth = HTTPBasicAuth()

    from . import models, views

    配置文件config.py

    import os

    basedir = os.path.abspath(os.path.dirname(__file__))

    SQLALCHEMY_DATABASE_URI = "mysql://root:123456@127.0.0.1/rest"

    SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')

    SQLALCHEMY_TRACK_MODIFICATIONS = True

    BASEDIR = basedir

    # 安全配置

    CSRF_ENABLED = True

    SECRET_KEY = 'jklklsadhfjkhwbii9/sdf\sdf'

    环境中使用mysql数据库,版本为mariadb 10.1.22。创建rest表

    $ mysql -uroot -p xxxxxx

    $ create database rest default charset utf8;

    创建数据库表app/models.py

    # -*- coding:utf-8 -*-

    from app import db, app

    from passlib.apps import custom_app_context

    from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, SignatureExpired, BadSignature

    class User(db.Model):

    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)

    username = db.Column(db.String(32), index=True)

    password = db.Column(db.String(128))

    # 密码加密

    def hash_password(self, password):

    self.password = custom_app_context.encrypt(password)

    # 密码解析

    def verify_password(self, password):

    return custom_app_context.verify(password, self.password)

    # 获取token,有效时间10min

    def generate_auth_token(self, expiration = 600):

    s = Serializer(app.config['SECRET_KEY'], expires_in = expiration)

    return s.dumps({ 'id': self.id })

    # 解析token,确认登录的用户身份

    @staticmethod

    def verify_auth_token(token):

    s = Serializer(app.config['SECRET_KEY'])

    try:

    data = s.loads(token)

    except SignatureExpired:

    return None # valid token, but expired

    except BadSignature:

    return None # invalid token

    user = User.query.get(data['id'])

    return user

    创建数据库users表:

    $ python db_create.py

    $ python db_migrate.py

    视图app/views.py

    from app import app, db, auth

    from flask import render_template, json, jsonify, request, abort, g

    from app.models import *

    @app.route("/")

    @auth.login_required

    def index():

    return jsonify('Hello, %s' % g.user.username)

    @app.route('/api/users', methods = ['POST'])

    def new_user():

    username = request.json.get('username')

    password = request.json.get('password')

    if username is None or password is None:

    abort(400) # missing arguments

    if User.query.filter_by(username = username).first() is not None:

    abort(400) # existing user

    user = User(username = username)

    user.hash_password(password)

    db.session.add(user)

    db.session.commit()

    return jsonify({ 'username': user.username })

    @auth.verify_password

    def verify_password(username_or_token, password):

    if request.path == "/api/login":

    user = User.query.filter_by(username=username_or_token).first()

    if not user or not user.verify_password(password):

    return False

    else:

    user = User.verify_auth_token(username_or_token)

    if not user:

    return False

    g.user = user

    return True

    @app.route('/api/login')

    @auth.login_required

    def get_auth_token():

    token = g.user.generate_auth_token()

    return jsonify(token)

    用户注册后密码加密存储,确认用户身份时密码解密。需要认证的api上添加@auth.login_required,它会在调用接口之前调用@auth.verify_password下的方法(此方法唯一)如verify_password。根据请求的路径选择不同的认证方式。

    测试

    使用curl命令测试接口

    注册用户:

    $ curl -i -X POST -H "Content-Type: application/json" -d '{"username":"admin","password":"123456"}' http://127.0.0.1:5000/api/register

    HTTP/1.0 200 OK

    Content-Type: application/json

    Access-Control-Allow-Origin: *

    Content-Length: 26

    Server: Werkzeug/0.12.2 Python/2.7.13

    Date: Wed, 20 Sep 2017 06:33:46 GMT

    {

    "username": "admin"

    }

    查看数据库:

    MariaDB [rest]> select * from users\G;

    *************************** 1. row ***************************

    id: 1

    username: admin

    password: $6$rounds=656000$etV4F3xLL0dwflX8$mLFX9l5dumBnQFtajGmey346viGuQ4bxR7YhQdKtB/nQH9ij2e3HHMEBPj.ef/o//4o9P2Wd3Y7dxQfjwR2hY/

    1 row in set (0.00 sec)

    获取token:

    curl -i -u admin:123456 -X GET -H "Content-Type: application/json" http://127.0.0.1:5000/api/login

    HTTP/1.0 200 OK

    Content-Type: application/json

    Access-Control-Allow-Origin: *

    Content-Length: 125

    Server: Werkzeug/0.12.2 Python/2.7.13

    Date: Wed, 20 Sep 2017 06:37:01 GMT

    "eyJhbGciOiJIUzI1NiIsImV4cCI6MTUwNTg5MDAyMSwiaWF0IjoxNTA1ODg5NDIxfQ.eyJpZCI6MX0.nUIKq-ZhFOiLPwZyUmfgWPfHYNy8o6eoR6lmzdsY0oQ"

    使用token调用api:

    $ curl -i -u eyJhbGciOiJIUzI1NiIsImV4cCI6MTUwNTg5MDAyMSwiaWF0IjoxNTA1ODg5NDIxfQ.eyJpZCI6MX0.nUIKq-ZhFOiLPwZyUmfgWPfHYNy8o6eoR6lmzdsY0oQ:unused -X GET -H "Content-Type: application/json" http://127.0.0.1:5000/

    HTTP/1.0 200 OK

    Content-Type: application/json

    Access-Control-Allow-Origin: *

    Content-Length: 15

    Server: Werkzeug/0.12.2 Python/2.7.13

    Date: Wed, 20 Sep 2017 06:38:22 GMT

    "Hello, admin"

    基于token的Flask api成功!!!!

    前端Vue.js

    前端使用vue的全家桶,axios前后端通讯,axios拦截器,localStorage保存token

    所使用的框架和库:

    vue2.0

    iview2.X

    axios

    vuex

    vue-router

    具体实现

    main.js

    // 初始化axios

    axios.defaults.baseURL = 'http://127.0.0.1:5000'

    axios.defaults.auth = {

    username: '',

    password: '',

    }

    // axios.interceptors.request.use((config) => {

    // console.log(config)

    // return config;

    // }, (error) => {

    // return Promise.reject(error)

    // })

    // axios拦截器,401状态时跳转登录页并清除token

    axios.interceptors.response.use((response) => {

    return response;

    }, (error) => {

    if (error.response) {

    switch (error.response.status) {

    case 401:

    store.commit('del_token')

    router.push('/login')

    }

    }

    return Promise.reject(error.response.data)

    })

    // 路由跳转

    router.beforeEach((to, from, next) => {

    if (to.meta.required) {

    // 检查localStorage

    if (localStorage.token) {

    store.commit('set_token', localStorage.token)

    // 添加axios头部Authorized

    axios.defaults.auth = {

    username: store.state.token,

    password: store.state.token,

    }

    // iview的页面加载条

    iView.LoadingBar.start();

    next()

    } else {

    next({

    path: '/login',

    })

    }

    } else {

    iView.LoadingBar.start();

    next()

    }

    })

    router.afterEach((to, from, next) => {

    iView.LoadingBar.finish();

    })

    路由

    export default new Router({

    routes: [{

    path: '/',

    name: 'index',

    component: Index,

    meta: {

    required: true,

    }

    }, {

    path: '/login',

    name: 'login',

    component: Login,

    }]

    })

    路由添加meta字段,作为需要认证路由的标志

    vuex

    export default new Vuex.Store({

    state: {

    token: ''

    },

    mutations: {

    set_token(state, token) {

    state.token = token

    localStorage.token = token

    },

    del_token(state) {

    state.token = ''

    localStorage.removeItem('token')

    }

    }

    })

    vuex中保存token,同时修改删除token和localStorage.token

    登录和登出

    登录:

    handleSubmit(name, form) {

    this.$refs[name].validate((valid) => {

    if (valid) {

    // 用户名密码简单验证后添加到axios的auth中

    this.$axios.defaults.auth = {

    username: form.username,

    password: form.password,

    }

    this.$axios.get('/api/login').then(response => {

    this.$Message.success("提交成功")

    let data = response.data

    // 保存token

    this.$store.commit('set_token', data)

    this.$router.push('/')

    }).catch(error => {

    this.$Message.error(error.status)

    })

    } else {

    this.$Message.error('表单验证失败!');

    }

    })

    }

    登出:

    logout() {

    this.$store.commit('del_token')

    this.$router.push('/login')

    }

    删除token并跳转到登录页

    flask和vue的token认证就完成了!!!!

    展开全文
  • vue token的实现

    2021-04-07 16:47:55
    1)用户第一次登录时,向服务器发起请求。... 3)设置请求头,将token放在请求头上,并让客户端的每次请求都带上token。 4)用户的每次请求,服务器都能根据token辨别出是哪个用户。每个用户都有一

    1、什么是Token
           Token是服务端生成的一串字符串,作为客户端进行请求时辨别客户身份的的一个令牌。当用户第一次登录后,服务器生成一个Token便将此Token返回给客户端。以后客户端的每次请求带上token,服务端就能辨别是哪一个用户。
           也可以将token比喻成一把钥匙,每当用户来访问服务器的时候就带上这把钥匙,然后去解服务器上的锁。如果锁解开了,那么用户就是登陆了,如果锁解不开,那么则提示用户未登录或登录已经失效。

    2、token的应用流程
           1)用户第一次登录时,向服务器发起请求。服务器根据账号和密码判断是否登录成功,如果是首次登录,服务器会生成一个新的token,并保存到数据库,数据库中存储了每个用户对应的token。最后服务器会把这个token返回给客户端。
           2)用户登录成功后,客户端将接收到的token存储到浏览器(localStorage或者sessionStorage)和vuex上。
           3)设置请求头,将token放在请求头上,并让客户端的每次请求都带上token。
           4)用户的每次请求,服务器都能根据token辨别出是哪个用户。每个用户都有一个不同的token。当然,为了再安全一点,我们还可以让用户每次把钥匙(token)发给我们的时候,再给他一把新钥匙(token),也就是说钥匙(token)只能使用一次,被劫持了咱也不怕。


    3、代码实现

    1)使用node.js搭建的服务器上处理登录请求,并返回token。token的生成是由后端生成的,这里就不深入到token的生成了。

    //模拟admin该用户第一次登录时,返回一个新的token
    router.post('/login',function (request,response){
        if(userName == 'admin' && userPwd == '123'){        //当账号密码正确
      		//token的生成需要引入一个可以生成token的库jsonwebtokens,这里只是模拟,就不生成了,直接给一个死数据
            let token = 'werty1234';   
            response.send({code:200,data:token})
        }else {
            response.send({code:400,msg:'账号或密码不正确'})
        }
    })
    

    2)在vuex上做处理,将接收到的token存储到state和浏览器中

    store/index.js

    export default new Vuex.Store({
      state: {
      	token: sessionStorage.getItem('token') ? sessionStorage.getItem('token') : ''
      },
      mutations: {
      //登录成功,存储信息到浏览器和state中
      	loginSuccess(state, data) { 
            state.token= data.token;
            sessionStorage.setItem('token', state.token);
        }
      },
      actions: {
      	 loginSuccess({commit}, data) {
            commit('loginSuccess', data)
        }
      }
    })
    

    3)设置请求头

    main.js

    //设置请求头
    Axios.defaults.headers.common['token'] = store.state.token;
    
    //每次发起请求时,判断是否有token,有则带上token
    Axios.interceptors.request.use(
        config => {
          if(sessionStorage.getItem('token')){
            config.headers.common['token'] = sessionStorage.getItem('token');
          }
          return config;
        },
        error => {
          return Promise.reject(error);
        }
    );
    

    4)登录成功,存储token

    this.$axios.post('服务器接口ip:端口/login',{
              userName:this.loginForm.username,
              userPwd:this.loginForm.pwd
          }).then(res=>{       
              if(res.data.code == 200){            //状态码为200,表示登录成功             
    		       var token = res.data.data;
    		       // 将接收到的token存储到vuex中
    		       this.$store.dispatch('loginSuccess',{token:token});       
    		       //跳转其他页面    
    		       this.$router.push('/index').catch(err=>{
    		           console.log(err)
            });
        }else{
            this.$message.error(res.data.msg);
        }
    }).catch(err=>{
        this.$message.error(err);
    })
          
    

    当用户登录成功后,已经完成了token的存储和请求头的设置。当该用户再向服务器发起请求后,都会带上这个token。服务器根据token识别用户身份,再对该用户的请求作出响应。

    5)最后也可以设置一个全局守卫,通过判断浏览器是否存储了token来判断用户是否登录。没有则跳到登录界面

    main.js

    //路由拦截
    router.beforeEach((to,from,next)=>{
      if(to.name == 'login'){         //如果是进入登录界面
        next();
      }else{         //进入其他页面
        let token = sessionStorage.getItem('token');
        if(token == '' || token == null){
          next('/login');        
        }else{
          next();
        }
      }
    });
    
    展开全文
  • vue token 过期处理

    2021-03-03 13:32:38
    1.登陆成功后储存token 可以利用 vuex 储存token 2.利用路由守卫处理 router.beforeEach((to,...如果有token && 跳转的是登陆页面 ,就跳转到主页面 if (!token && to.name !== LOGIN_PAGE...

    1.登陆成功后储存token  可以利用 vuex 储存token 

    2.利用路由守卫处理

     

    router.beforeEach((to, from, next) => {

     

    })

     

     

    3.我们可以判断进去的路由的名字是不是 login  如果没有token  或者 跳转的路径不是登陆页面 就跳转到登陆页面

    如果有token &&  跳转的是登陆页面 ,就跳转到主页面

    if (!token && to.name !== LOGIN_PAGE_NAME) {
        // 未登录且要跳转的页面不是登录页
        next({
          name: LOGIN_PAGE_NAME // 跳转到登录页
        })
      } else if (!token && to.name === LOGIN_PAGE_NAME) {
        // 未登陆且要跳转的页面是登录页
        next() // 跳转
      } else if (token && to.name === LOGIN_PAGE_NAME) {
        // 已登录且要跳转的页面是登录页
        next({
          name: homeName // 跳转到homeName页
        })
      } else {
        if (store.state.user.hasGetInfo) {
          turnTo(to, store.state.user.access, next)
        } else {
          store.dispatch('getUserInfo').then(user => {
            console.log(token);
            // 拉取用户信息,通过用户权限和跳转的页面的name来判断是否有权限访问;access必须是一个数组,如:['super_admin'] ['super_admin', 'admin']
            turnTo(to, user.access, next)
          }).catch(() => {
            setToken('');
            next({
              name: 'login'
            })
          })
        }
      }

     

    转载于:https://www.cnblogs.com/guangzhou11/p/11546966.html

    展开全文
  • 前台用户登录成功后,后台给前台返回token。之后前台给后台发请求每次携带token。原理也非常简单:前天在请求头中添加 Authorization,如下image.png后台取到值,然后去用户表的api_token列进行匹配,如果查到说明...
  • 本文介绍了一些Vue和axios的实用技巧,解决前端API调用中access_token的处理问题,包括:Promise的链式调用,axios的拦截器,vue-router记录导航历史等。问题分析前后端完全分离的项目中,一个前端应用会访问多个...
  • 首先回顾一下token:token认证是RESTFUL.api的一个很重要的部分,通过token认证和token设置,后端会有一个接口传给前台:http://localhost/yiiserver/web/index.php/token?client_appid=aaa&client_appkey=bbb...
  • 在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下:1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token3、前端拿到...
  • vue token的简单理解和使用

    千次阅读 2020-09-06 16:06:26
    什么是token ? 客户端向服务端请求数据,服务端需要查询客户端的用户...这里使用element库+vue 做演示 template中 <!-- 登录表单 --> <el-form :model="loginForm" ref="LoginFormRef" :rules="loginF
  • 1. 安装插件 npm install jwt-decode --save 2. 在需要使用的地方引入 import jwtDecode from 'jwt-decode' const code = jwtDecode(res.data.data.accessToken) console.log(code)// 就可以解析成功了 ...
  • 现在的项目使用了vue + flask的框架,后端flask用token来做验证,但是会面临一个token过期的问题,设置过长的token过期时间或者设置一个refresh token的时间来处理都不能满足我这个项目的需求,我们希望的是在token...
  • 指路牌符合一下关键词,这篇博客有可能会对你有帮助不使用工厂函数的Flask应用不使用蓝本的Flask应用Flask跨域配置基于Token的登录状态管理Flask+VueVue路由拦截Axios 钩子适用场景这是一篇个人博客搭建的记录博客,...
  • 登录的token思维和处理 思维: 将登录成功之后的 token,保存到客户端的 sessionStorage 中 1.1 项目中除了登录之外的其他API接口,必须在登录之后才能访问(路由导航守卫) 1.2 token 只应在当前网站打开期间生效...
  • 5、所以个人建议: 将登陆信息等重要信息存放为session 其他信息如果需要保留,可以放在cookie中 Token 和 Session 的区别: session和 token并不矛盾,作为身份认证token安全性比session好,因为每个请求都有签名...
  • 推荐阅读 点击标题可跳转.NET Core+Vue后台管理基础框架C#桌面开发的未来WebWindow如何提升.NET控制台应用体验? 看完本文有收获?请转发分享给更多人 关注「DotNet」加星标,提升.Net技能 好文章,我在看❤️
  • "取消", type: "warning" } ).then(() => { // store.dispatch('FedLogOut').then(() => { // location.reload() // 为了重新实例化vue-router对象 避免bug // }) }); } return Promise.reject("error"); } else { ...
  • 从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之九如何进行用户权限控制在一般的前后端分离的web系统开发中,在服务端除了对用户数据的缓存之外,往往在某些接口上,还涉及到对用户...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,511
精华内容 2,204
关键字:

vuetoken

vue 订阅