Vue 项目 Vue + restfulframework
实现登录认证
- django
views
class MyResponse():
def __init__(self):
self.status = 100
self.msg = None
@property
def get_dic(self):
return self.__dict__
#token
def get_token(username):
import hashlib
import time
md = hashlib.md5()
# update内必须传bytes格式
md.update(username.encode('utf-8'))
md.update(str(time.time()).encode('utf-8'))
return md.hexdigest()
#认证
class Login(APIView):
authentication_classes = []
def post(self, request):
response = MyResponse()
name = request.data.get('username')
pwd = request.data.get('password')
user = models.User.objects.filter(username=name, password=pwd).first()
print(name,pwd)
name1 =request.GET.get('username')
print(name1)
if user:
response.msg = '登陆成功'
response.username = name
# 登陆成功,返回一个随机字符串,以后在发请求,都携带这个字符串
token = get_token(name)
response.token = token
# 把随机字符串保存到数据库,有就更新,没有就创建
# ret=models.UserToken.objects.update_or_create(user_id=user.id,kwargs={'token':token})
ret = models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
else:
response.msg = '用户名或密码错误'
response.status = 101
obj = JsonResponse(response.get_dic)
obj['Access-Control-Allow-Origin']='*'
return obj
#解决跨域问题 中间件
from django.utils.deprecation import MiddlewareMixin
class CorsMiddleWare(MiddlewareMixin):
def process_response(self,request,response):
if request.method=="OPTIONS":
print(111)
#不能加*
response["Access-Control-Allow-Headers"]="*"
response["Access-Control-Allow-Origin"] = "*"
response['Access-Control-Allow-Methods'] = 'POST'
return response
setting
把中间件添加到setting的配置中
注释csrftoken认证
MIDDLEWARE = [
'app01.views.CorsMiddleWare',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
urls
urlpatterns = [
re_path('login/', views.Login.as_view()),
]
- Vue
安装包
cnpm install --save axios vuex
npm install vue-cookie --save
route.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import Index from '../src/components/index.vue'
// import Login from '../src/components/Login.vue'
Vue.use(Router);
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/index',
name: 'Index',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
// 两种都可以,要不上面导入进来,或者直接定vue组件的路径
// component: () => import(/* webpackChunkName: "about" */ '../src/components/index.vue')
component:Index
},
{
path: '/login',
name: 'Login',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../src/components/Login.vue')
}
]
})
store.js
import Vue from 'vue'
import Vuex from 'vuex'
import Cookie from 'vue-cookies'
Vue.use(Vuex);
export default new Vuex.Store({
state: {
username:Cookie.get('username'),
token:Cookie.get('token')
// Cookie.get('username') Cookie.get('token')
},
mutations: {
//组件中通过this.$store.commit(参数)调用
saveToken (state,data) {
state.username = data.username;
state.token = data.token;
Cookie.set('username',data.username,'1min');
Cookie.set('token',data.token,'1min')
},
//清空token和cookie
clearToken (state) {
state.username = null;
state.token = null;
Cookie.remove('username');
Cookie.remove('token')
}
},
actions: {
}
})
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Axios from 'axios'
import VueCookie from 'vue-cookies'
// import 'bootstrap/dist/css/bootstrap.css'
Vue.prototype.$axios = Axios;
Vue.prototype.$Cookies = VueCookie;
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');
App.vue
<template>
<div>
<!--首页里面永远都是固定的东西-->
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">
<img alt="Brand">
</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li>
<router-link to="/index">首页</router-link>
</li>
<li>
<router-link to="/micro">学位课</router-link>
</li>
<li>
<router-link to="/course">课程</router-link>
</li>
<li>
<router-link to="/news">深科技</router-link>
</li>
<li v-if=this.$store.state.username>
<span>欢迎 {{ this.$store.state.username }} 登录
<a @click="logout">注销</a>
</span>
</li>
<li v-else="">
<router-link to="/login">登录</router-link>
</li>
<!--{{ this.$store.state.username }}-->
</ul>
</div>
</div>
</nav>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
methods: {
logout() {
this.$store.state.username = '';
this.$store.state.token = ''
}
}
}
</script>
<style>
</style>
components --> Login.vue
<template>
<div class="container ">
<h2 class="modal-title">登录页面</h2>
<p></p>
<p></p>
<p></p>
<div class="form-group " >
<label for="1111" >
用户名
</label>
<input type="text" class="form-control " v-model="username" placeholder="username" id="1111">
</div>
<div class="form-group ">
<label for="">
密码
</label>
<input type="text" class="form-control " placeholder="password" v-model="password">
</div>
<p>
{{ msg }}
</p>
<button @click="DoLogin()" class="btn btn-success">提交</button>
</div>
</template>
<script>
export default {
name: "Login",
data(){
return{
username:'',
password:'',
msg :''
}
},
methods:{
DoLogin(){
let _this = this;
this.$axios.request({
url:'http://127.0.0.1:8000/login/',
method:"POST",
data:{
"username": this.username,
"password": this.password
},
// responseType:'json',
}).then(function (res) {
window.console.log(res.data)
window.console.log(res.data.status)
if (res.data.status == 100){
_this.title = res.data;
_this.$store.commit('saveToken',res.data)
_this.$router.push('/index');
}else {
_this.msg = res.data.msg;
_this.$data.passowrd = ''
}
})
}
}
}
</script>
<style scoped>
</style>
components -> index.vue
<template>
<div class="row">
<h2>
{{ msg }}
</h2>
<div class="col-md-2">
<div style="background-color: #2aabd2">
1
</div>
</div>
<div style="width: 100%">
<div style="background-color: #8c8c8c">
2
</div>
</div>
</div>
</template>
<script>
export default {
name: "Index",
data() {
return {
msg: '这是首页'
}
}
}
</script>
<style scoped>
</style>