1.最简单的用户输入密码账号,查询用户数据库登录方式
view里面的主要逻辑
class LoginView(View):
def get(self, request, *args, **kwargs):
if request.user.is_authenticated:
return HttpResponseRedirect(reverse("index"))
login_form = DynamicLoginForm()
return render(request, "login.html", {
"login_form":login_form
})
def post(self, request, *args, **kwargs):
login_form = LoginForm(request.POST)
if login_form.is_valid():
user_name = login_form.cleaned_data["username"]
password = login_form.cleaned_data["password"]
user = authenticate(username=user_name, password=password)
if user is not None:
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
return render(request, "login.html", {"msg":"用户名或密码错误", "login_form": login_form})
else:
return render(request, "login.html", {"login_form": login_form})
view里面牵扯到的两个form
class LoginForm(forms.Form):
username = forms.CharField(required=True, min_length=2)
password = forms.CharField(required=True, min_length=3)
class DynamicLoginForm(forms.Form):
mobile = forms.CharField(required=True, min_length=11, max_length=11)
captcha = CaptchaField()
is_valid是adjango提供的一个很好用的验证表单的一个逻辑
2.发送动态验证码
class SendSmsView(View):
def post(self, request, *args, **kwargs):
send_sms_form = DynamicLoginForm(request.POST)
re_dict = {}
if send_sms_form.is_valid():
mobile = send_sms_form.cleaned_data["mobile"]
#随机生成数字验证码
code = generate_random(4, 0)
re_json = send_single_sms(yp_apikey, code, mobile=mobile)
if re_json["code"] == 0:
re_dict["status"] = "success"
r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0, charset="utf8", decode_responses=True)
r.set(str(mobile), code)
r.expire(str(mobile), 60*5) #设置验证码五分过期
else:
re_dict["msg"] = re_json["msg"]
else:
for key, value in send_sms_form.errors.items():
re_dict[key] = value[0]
return JsonResponse(re_dict)
在这里我用的是云片网,
if re_json[“code”] == 0:
re_dict[“status”] = “success”
r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0, charset=“utf8”, decode_responses=True)
r.set(str(mobile), code)
相关配置可以在云片网文档上查询,这里用到了redis,大家可以去github上下载
cd 到下载目录,运行
在后续调试运行时要保持redis一直运行,不然就会报错,我在这卡了一个小时,被自己蠢哭
可以使用以下代码来调试一下redis,
import redis
r = redis.Redis(host='localhost', port=6379, db=0, charset="utf8", decode_responses=True)
r.set("mobile", "123")
r.expire("mobile", 1)
import time
time.sleep(1)
print(r.get("mobile"))
3.动态验证码登录
class DynamicLoginView(View):
def post(self, request, *args, **kwargs):
login_form = DynamicLoginPostForm(request.POST)
dynamic_login = True
if login_form.is_valid():
mobile = login_form.cleaned_data["mobile"]
existed_users = UserProfile.objects.filter(mobile=mobile)
if existed_users:
user = existed_users[0]
else:
#xinjian新建用户
user = UserProfile(username=mobile)
password = generate_random(10, 2)
user.set_password(password)
user.mobile = mobile
user.save()
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
d_form = DynamicLoginForm()
return render(request, "login.html", {"login_form": login_form,
"d_form": d_form,
"dynamic_login": dynamic_login})
这里我将验证码的验证过程写到了form里面
class DynamicLoginPostForm(forms.Form):
mobile = forms.CharField(required=True, min_length=11, max_length=11)
code = forms.CharField(required=True, min_length=4, max_length=4)
password = forms.CharField(required=True)
def clean_code(self):
mobile = self.data.get("mobile")
code = self.data.get("code")
r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0, charset="utf8", decode_responses=True)
redis_code = r.get(str(mobile))
if code != redis_code:
raise forms.ValidationError("验证码不正确")
return code
3.注册功能
class RegisterView(View):
def get(self, request, *args, **kwargs):
register_get_form = RegisterGetForm()
return render(request, "register.html", {
"register_get_form": register_get_form
})
def post(self, request, *args, **kwargs):
register_post_form = RegisterPostForm(request.POST)
if register_post_form.is_valid():# xinjian新建用户
mobile = register_post_form.cleaned_data["mobile"]
password = register_post_form.cleaned_data["password"]
user = UserProfile(username=mobile)
user.set_password(password)
user.mobile = mobile
user.save()
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
register_get_form = RegisterGetForm()
return render(request, "register.html", {"register_get_form": register_get_form,
"register_post_form": register_post_form,
})
同样将一部分逻辑写到了form里面,
class RegisterGetForm(forms.Form):
captcha = CaptchaField()
class RegisterPostForm(forms.Form):
mobile = forms.CharField(required=True, min_length=11, max_length=11)
code = forms.CharField(required=True, min_length=4, max_length=4)
password = forms.CharField(required=True)
def clean_mobile(self):
mobile = self.data.get("mobile")
users = UserProfile.objects.filter(mobile=mobile)
if users:
raise forms.ValidationError("该手机号已经注册,如果忘记密码请用验证码动态登录")
return mobile
def clean_code(self):
code = self.data.get("code")
mobile = self.data.get("mobile")
r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0, charset="utf8", decode_responses=True)
redis_code = r.get(str(mobile))
if code != redis_code:
raise forms.ValidationError("验证码不正确")
#yanzheng手机号码是否已经注册
return code
url相关配置
附上前端相关源码,有需要可以下载练习
同时这里有一个cookie和session的登陆原理的问题
1,session 在服务器端,cookie 在客户端(浏览器)
2,session 默认被存在在服务器的一个文件里(不是内存)
3,session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id)
4,session 可以放在 文件、数据库、或内存中都可以。
5,用户验证这种场合一般会用 session