版权声明:Copyright 2000-2018 Max.Bai All rights Reserved. https://blog.csdn.net/max229max/article/details/84379767

不改变Django原登录系统实现vue登录

Max.Bai

2018-11


0. 背景

原有系统登录功能为django自带功能,基本满足现有使用
    现在需要做另外一个系统,用vue做前端,后端还使用原来的django,那么账号就可以使用原来的账号了
    查找网络,vue 结合django 实现登陆,基本解决方案是用drf 和rest_framework.authtoken
    实现token,vue获得token,携带token访问后台数据
    因为我后台是原有django,并且本来就有页面,要用rest_framework.authtoken,就要大改造,并且原有登录系统可能无法使用
    后来就考虑,原有请求只要带csrftoken就可以请求,所以就有一下思路:
    1. 请求django登录页面,post登陆请求拿到csrftoken
    2. 携带csrftoken请求后台数据
    完美实现不动原有登录系统实现登录功能

假设你已经基本熟悉使用vue

1. 准备

1.1 npm 安装axios

或者你使用vue resource 或者使用ajax,总之你要有请求django后台的工具
    每次请求都要导入axios,不用
    直接在main.js 导入并添加axios属性,后面就直接使用this.$axios 了
 

    import axios from 'axios'

    Vue.prototype.$axios = axios
    axios.defaults.headers.post["X-CSRFToken"] = getCookie("csrftoken")  

1.2 给axios设置代理

不用设置也可以,主要是给后端请求加前缀,做区别用
        在项目config/index.js里面修改proxyTable
        

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


   

1.3 编写cookie基本操作js文件

比如,getcookies,setcookie,网上大把

    function getCookie(name)
    {
        var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
        if(arr=document.cookie.match(reg))
            return unescape(arr[2]);
        else
            return null;
    }

    function setCookie(name,value, days)
    {
        var exp = new Date();
        exp.setTime(exp.getTime() + days*24*60*60*1000);
        document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
    }

    export {
        getCookie,
        setCookie
    }

 

2. 登录页面

2.1 vue中编写一个简单的登录页面

    2个输入框,一个登录按钮
    导入cookies 操作js文件
    登录数据 严格按照下面的内容,因为django默认的登录系统需要这3个值,并且名字是固定的

    form: {
        csrfmiddlewaretoken: '',
        username: '',
        password: ''
      },


    

2.2. 获得csrfmiddlewaretoken

登录页面打开后主动请求django登录页面,默认django登录页面url 为/accounts/login/,如果你没有修改的情况下。
    访问的目的是获得登录页面的csrfmiddlewaretoken,方便后面登录的时候提交数据。

    mounted () {
        var vm = this;
          vm.$axios({
            method: 'get',
            baseURL: '/api',    // 这个就是代理前缀 查看1.2
            url:'/accounts/login/',
          })
          .then(function(response){
            const regex = /csrfmiddlewaretoken' value='(.*)'/gm;
            var arr, reg = new RegExp("csrfmiddlewaretoken' value='(.*)'");

            if (arr = response.data.match(reg))
              vm.form.csrfmiddlewaretoken = unescape(arr[1])
            else
              console.log('not found crsf value')
          })
      },


     

2.3 提交登录信息


    登录按钮事件,post form里面的内容到django 登录页面url /accounts/login/
    同时添加跳转url,就是next=xxxx, 登录成功后django自动跳转, 应为你不添加跳转,django会默认跳转到/account/profile页面,而这个页面默认是没有的就会报错
    跳转url可以自己定义,这里跳转到获取当前用户信息的页面,登录成功的同时获取用户信息,这个接口要自己在django实现
    如果登录成功写cookie信息,写什么自己定义,这里写了用户信息和登录成功的标志,方便后面判断是否登录
  

 login () {
      var vm = this;
      this.$axios({
        method: 'post',
        baseURL: '/api',
        url:'/accounts/login/?next=/api/public/getuserinfo',  //别忘记给next跳转的url添加代理前缀
        data: vm.form,
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'        //django 登录默认是form表单,需要添加
          },
        transformRequest: [            // django 登录默认是form表单,axios默认是json格式,说以发送数据要通过transformRequest转换为form格式
          function (data) {
            // Do whatever you want to transform the data
            let ret = ''
            for (let it in data) {
              ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
              }
            return ret
          }
        ]
      }).then(function(response){
        //登录成功后调到后页面,也就是next后面的url接口返回的数据在这里
        // 验证返回正确,这里返回的是用户信息,写cookie
        if(response.data.code === 0){
          window.location = '/projects'  //登录成功后跳转到home页面
          setCookie('login', 'success', 15)
          setCookie('username', response.data.data.username, 15)
          setCookie('userid', response.data.data.id, 15)
        } else {
          vm.$message.error('Login failed!!');
        }
      })
    }


    这样就已经登录成功了,成功后页面cookies 包含csrftoken和sessionid 2个默认django会写的内容,同时还有自己设置的cookie内容


3. 发送业务请求


    登录成功后后续的请求如何让django知道是登录状态哪?
    发送请求的同时带上headers  X-CSRFToken  值为cookies里面csrftoken的内容
    每次发送都要设置headers? 好麻烦
    直接在main.js 里面导入axios 的时候设置默认header
 

    import axios from 'axios'

    Vue.prototype.$axios = axios
    axios.defaults.headers.post["X-CSRFToken"] = getCookie("csrftoken")  


4. 简单路由校验


    如果没有登录,自动跳转到登录页面
    如果登录成功,直接next
    在router/index.js 添加
    

router.beforeEach(function (to, from, next) {
      console.log('to', to.name)
      if (IsLogin()) {
        console.log('login true')
        if (to.name === 'login') {
          next()
          // router.push({name: 'projects'});
        } else {
          next()
        }
      } else {
        console.log('login false')
        if (to.name === 'login') {
          next()
        } else {
          router.push({name: 'login'});
        }
      }
    });
    
    function IsLogin () {
      console.log('login check....')
      if (getCookie('login') === 'success') return true   // 这里验证登录成功是写的cookie
      else return false
    }


    
    有人会说,这个是不是太简单了,修改cookie就可以制造登录状态
    其实没关系的,你通过了校验没用,后台会校验csrftoken的

5. 没有了,要贴图的,但是图他丑就不贴了

 

 

Logo

前往低代码交流专区

更多推荐