版权声明:Copyright 2000-2018 Max.Bai All rights Reserved. https://blog.csdn.net/max229max/article/details/84379767
Max.Bai
2018-11
原有系统登录功能为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
或者你使用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")
不用设置也可以,主要是给后端请求加前缀,做区别用
在项目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’即可
}
}
},
比如,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个输入框,一个登录按钮
导入cookies 操作js文件
登录数据 严格按照下面的内容,因为django默认的登录系统需要这3个值,并且名字是固定的
form: {
csrfmiddlewaretoken: '',
username: '',
password: ''
},
登录页面打开后主动请求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')
})
},
登录按钮事件,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内容
登录成功后后续的请求如何让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")
如果没有登录,自动跳转到登录页面
如果登录成功,直接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的