vue+django实现简单注册登录和cookie储存

     阅读:27

vue+django实现简单注册登录和cookie储存

暂时仅支持chrome测试,ie不支持这个split(’;’)
cookie添加遇到samesite阻碍,所以准备从前端直接添加cookie
注意: js里多个cookie需要单独设置,每次设置一个

document.cookie = "username=" + response.data.name;
document.cookie = "id=" + response.data.id;

django views.py

from django.shortcuts import render
from django.views.decorators.http import require_http_methods
from django.core import serializers
from django.http import JsonResponse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render, HttpResponse
import json
from loginapp.models import User
# Create your views here.

# @method_decorator(csrf_exempt, name='dispatch')

@csrf_exempt
@require_http_methods(["POST"])
def add_user(request):
    response = {}
    try:
        try:
            idn = User.objects.last().id
        except:
            idn = 0
        print(request.body.decode())
        data = json.loads(request.body.decode())
        print(data)
        if User.objects.filter(username=data.get('username')):
            response['msg'] = '用户名已存在'
            response['error_num'] = 2
        else:
            user = User(id=idn+1,nickname=data.get('nickname'),username=data.get('username'),password=data.get('password'))
            user.save()
            response['msg'] = 'success\n唯一id: ' + str(idn+1)
            response['error_num'] = 0
    except Exception as e:
        response['msg'] = str(e)
        response['error_num'] = 1
    return JsonResponse(response)

@csrf_exempt
@require_http_methods(["POST"])
def login(request):
    response = {}
    try:
        data = json.loads(request.body.decode())
        print(data)
        if User.objects.filter(username=data.get('username'),password=data.get('password')):
            response['msg'] = 'success'
            response['name'] = data.get('username')
            response['id'] = User.objects.filter(username=data.get('username')).first().id
            response['error_num'] = 0
        elif not User.objects.filter(username=data.get('username')):
            response['msg'] = '用户不存在'
            response['error_num'] = 2
        elif User.objects.filter(username=data.get('username')):
            response['msg'] = '密码错误,请联系管理员'
            response['error_num'] = 3
    except Exception as e:
        response['msg'] = str(e)
        response['error_num'] = 1
    ret = JsonResponse(response)
    if User.objects.filter(username=data.get('username'),password=data.get('password')):
        ret.set_cookie('username',data.get('username'))
        ret.set_cookie('id',User.objects.filter(username=data.get('username')).first().id)
    return ret

vue main.vue

<template>
	<div id="main">
		<p>TEST</p>
		<p>{{user}}</p>
		<form style="display: inline" @click="register">
			<button type="button">注册</button>
		</form>
		<form v-if="!ck" style="display: inline" @click="login">
			<button type="button">登录</button>
		</form>
		<form v-if="ck" style="display: inline" @click="out">
			<button type="button">退出登录</button>
		</form>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				user: "请登录",
				ck: false,
			};
		},
		methods: {
			// 点击登录时候触发的事件
			register() {
				this.$router.push("register");
			},
			login() {
				if (document.cookie) {
					var cookie = {};
					var line = document.cookie.split("; ");
					cookie[line[0].split("=")[0]] = line[0].split("=")[1];
					cookie[line[1].split("=")[0]] = line[1].split("=")[1];
					console.log(cookie);
					this.user = "欢迎:" + cookie["username"] + "(id:" + cookie["id"] + ")";
				} else {
					this.$router.push("login");
				}
			},
			out() {
				var exdate = new Date();
				exdate.setDate(exdate.getDate() + -1);
				document.cookie = "username=''; expires=" + exdate.toGMTString();
				document.cookie = "id=''; expires=" + exdate.toGMTString();
				if (!document.cookie) {
					console.log("cookie清除完成");
				}
				this.user = "请登录";
				this.ck = false;
			}
		},
		created() {
			if (document.cookie) {
				this.ck = true;
				var cookie = {};
				var line = document.cookie.split("; ");
				cookie[line[0].split("=")[0]] = line[0].split("=")[1];
				cookie[line[1].split("=")[0]] = line[1].split("=")[1];
				console.log(cookie);
				this.user = "欢迎:" + cookie["username"] + "(id:" + cookie["id"] + ")";
			}
		}
	}
</script>

<style lang="less"></style>

vue register.vue

<template>
	<div id="register">
		<h3>
			<span style="display:inline-block;width:200px;text-align:right;">用户注册</span>
		</h3>
		<form action="" method="post" @submit.prevent="submit">
			<p>
				<span style="display:inline-block;width:80px;text-align:right;">昵称:</span>
				<input type="text" v-model="nickname" value="" autocomplete>
				<i v-if="nnerror" style="color: #ff0000;font-size: small;">{{nnerror}}</i>
				<i v-if="!nnerror" style="color: #00ff00;font-size: small;"></i>
			</p>
			<p>
				<span style="display:inline-block;width:80px;text-align:right;">用户名:</span>
				<input type="text" v-model="username" value="" autocomplete>
				<i v-if="unerror" style="color: #ff0000;font-size: small;">{{unerror}}</i>
				<i v-if="!unerror" style="color: #00ff00;font-size: small;"></i>
			</p>
			<p>
				<span style="display:inline-block;width:80px;text-align:right;">密码:</span>
				<input type="password" v-model="password" value="" autocomplete>
				<i v-if="pwerror" style="color: #ff0000;font-size: small;">{{pwerror}}</i>
				<i v-if="!pwerror" style="color: #00ff00;font-size: small;"></i>
			</p>
			<p>
				<span style="display:inline-block;width:80px;text-align:right;">确认密码:</span>
				<input type="password" v-model="pwagain" autocomplete>
				<i v-if="pwaerror" style="color: #ff0000;font-size: small;">{{pwaerror}}</i>
				<i v-if="!pwaerror" style="color: #00ff00;font-size: small;"></i>
			</p>
			<span style="display:inline-block;width:160px;text-align:right;">
				<!-- disabled需使用v-bind绑定 -->
				<input v-if="check" type="button" v-bind:disabled="check" style="cursor:not-allowed;" value="注册">
				<input v-if="!check" type="button" value="注册" v-on:click="add()">
			</span>
		</form>
		<!-- 正常识别\n -->
		<div style="white-space: pre-line;">{{message}}</div>
		<!-- vue需使用@click+函数 -->
		<form style="display: inline" @click="main">
			<button type="button">主页</button>
		</form>
	</div>
</template>

<script>
	export default {
		// 数据
		data() {
			return {
				list: "",
				check: true,
				nnerror: "输入你的昵称",
				unerror: "输入用户名",
				pwerror: "输入密码",
				pwaerror: "再次输入密码确认",
				nickname: "",
				username: "",
				password: "",
				pwagain: "",
				message: "",
			};
		},
		// 监听变量
		watch: {
			nickname: function() {
				if (this.nickname != null) {
					sessionStorage.setItem("rnickname", this.nickname);
					if (this.nickname.length == 0) {
						this.nnerror = "输入你的昵称";
					} else if (this.nickname.length > 10) {
						this.nnerror = "昵称长度限制10";
					} else {
						this.nnerror = false;
					}
				}
			},
			username: function() {
				if (this.username != null) {
					sessionStorage.setItem("rusername", this.username);
					if (this.username.length == 0) {
						this.unerror = "输入用户名";
					} else if (this.username.length > 14 || this.username.length < 6) {
						this.unerror = "昵称长度限制6~14";
					} else {
						this.unerror = false;
					}
				}
			},
			password: function() {
				if (this.password != null) {
					sessionStorage.setItem("rpassword", this.password);
					if (this.password.length == 0) {
						this.pwerror = "输入密码";
					} else if (this.password.length > 20 || this.password.length < 6) {
						this.pwerror = "昵称长度限制6~20";
					} else {
						this.pwerror = false;
					}
				}
			},
			pw: function() {
				if (this.pwagain != null) {
					sessionStorage.setItem("rpwagain", this.pwagain);
					if (this.pwagain.length == 0) {
						this.pwaerror = "再次输入密码确认";
					} else if (this.password != this.pwagain) {
						this.pwaerror = "重复密码错误";
					} else {
						this.pwaerror = false;
					}
				}
			},
			dateRange: function() {
				if (this.nnerror == false && this.unerror == false && this.pwerror == false && this.pwaerror ==
					false) {
					this.check = false;
				} else {
					this.check = true;
				}
			}
		},
		created() {
			// 获取缓存
			if (this.nickname != null) {
				this.nickname = sessionStorage.getItem("rnickname");
			}
			if (this.username != null) {
				this.username = sessionStorage.getItem("rusername");
			}
			if (this.password != null) {
				this.password = sessionStorage.getItem("rpassword");
			}
			if (this.pwagain != null) {
				this.pwagain = sessionStorage.getItem("rpwagain");
			}

		},
		// 绑定变量监控
		computed: {
			dateRange() {
				const {
					nnerror,
					unerror,
					pwerror,
					pwaerror
				} = this;
				return {
					nnerror,
					unerror,
					pwerror,
					pwaerror
				}
			},
			pw() {
				const {
					password,
					pwagain,
				} = this;
				return {
					password,
					pwagain,
				}
			}
		},
		methods: {
			// 提交post
			/*submit: function(event){
				var formData = JSON.stringify({
					nickname: this.nickname,
					username: this.username,
					password: this.password
				});
				this.$http.post('http://localhost:8000/api/add_user', formData).then((response) => {
					// success callback
					console.log(response);
					if (response.data.error_num == 0) {
						this.message = "返回: " + response.data.msg + "\n注册成功";
					} else {
						this.message = "返回: " + response.data.msg;
					}
				}, (response) => {
					// error callback
					console.log(response);
					this.message = "返回: " + response.data + "\n注册失败";
				});
			},*/
			// 返回主页
			main() {
				this.$router.push("/");
			},
			// 注册post
			add: function() {
				var formData = JSON.stringify({
					nickname: this.nickname,
					username: this.username,
					password: this.password
				});
				this.$http.post('http://localhost:8000/api/add_user', formData).then((response) => {
					// success callback
					console.log(response);
					if (response.data.error_num == 0) {
						this.message = "返回: " + response.data.msg + "\n注册成功";
					} else {
						this.message = "返回: " + response.data.msg;
					}
				}, (response) => {
					// error callback
					console.log(response);
					this.message = "返回: " + response.data + "\n注册失败";
				});
			}
		}
	};
</script>

<style>
</style>

vue login.vue

<template>
	<div>
		<h3>
			<span style="display:inline-block;width:200px;text-align:right;">用户登录</span>
		</h3>
		<form action="" method="post" @submit.prevent="submit">
			<p>
				<span style="display:inline-block;width:80px;text-align:right;">用户名:</span>
				<input type="text" v-model="username" value="" autocomplete>
				<i v-if="unerror" style="color: #ff0000;font-size: small;">{{unerror}}</i>
			</p>
			<p>
				<span style="display:inline-block;width:80px;text-align:right;">密码:</span>
				<input type="password" v-model="password" value="" autocomplete>
				<i v-if="pwerror" style="color: #ff0000;font-size: small;">{{pwerror}}</i>
			</p>
			<span style="display:inline-block;width:160px;text-align:right;">
				<!-- disabled需使用v-bind绑定 -->
				<input type="submit" value="登录">
			</span>
		</form>
		<!-- 正常识别\n -->
		<div style="white-space: pre-line;">{{message}}</div>
		<p>{{cktest}}</p>
		<form style="display: inline" @click="main">
			<button type="button">主页</button>
		</form>
	</div>
</template>

<script>
	export default {
		// 数据
		data() {
			return {
				list: "",
				unerror: "",
				pwerror: "",
				username: "",
				password: "",
				message: "",
				cktest: "",
			};
		},
		methods: {
			// 提交post
			submit: function(event) {
				var un = "";
				var pw = "";
				var n = -1;
				if (this.username == null || this.username == "") {
					this.unerror = "用户名不能为空";
				} else {
					un = this.username;
				}
				if (this.password == null || this.password == "") {
					this.pwerror = "密码不能为空";
				} else {
					pw = this.password;
				}
				if (this.password != null && this.password != "" && this.username != null && this.username != "") {
					var formData = JSON.stringify({
						username: un,
						password: pw
					});
					this.$http.post('http://localhost:8000/api/login', formData).then((response) => {
						// success callback
						console.log(response);
						this.message = "\n返回: " + response.data.msg;
						// test 简单解决samesite问题,在前端添加cookie
						if(response.data.error_num == 0){
							document.cookie = "username="+response.data.name+"; id="+response.data.id
							// window.localStorage.setItem("username",response.data.username);
							this.cktest = document.cookie;
							this.$router.push("/");
						}
					}, (response) => {
						// error callback
						console.log(response);
						this.message = "\n返回: " + response.data.msg;
					});
				}
			},
			// 返回主页
			main() {
				this.$router.push("/");
			},
		},
		watch: {
			username: function() {
				if (this.username != null) {
					sessionStorage.setItem("lusername", this.username);
					if (this.username.length != 0) {
						this.unerror = "";
					}
				}
			},
			password: function() {
				if (this.password != null) {
					sessionStorage.setItem("lpassword", this.password);
					if (this.password.length != 0) {
						this.pwerror = "";
					}
				}
			},
		},
		created() {
			// 获取缓存
			if (this.username != null) {
				this.username = sessionStorage.getItem("lusername");
			}
			if (this.password != null) {
				this.password = sessionStorage.getItem("lpassword");
			}
		},
	}
</script>

<style>
</style>