博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django实现注册登录 --- 传统HTTP Basic认证+Session会话
阅读量:3923 次
发布时间:2019-05-23

本文共 11590 字,大约阅读时间需要 38 分钟。

采用Django实现的注册登录功能

项目地址:https://github.com/ylpxzx/Login_DjangoAuth

主要实现内容

在这里插入图片描述

效果演示

未登录情况下,无法访问需要登录认证的页面

点击右上角的“气泡”按钮,未登录情况下,自动跳转到登录页面

在这里插入图片描述

自动跳转到登录页
在这里插入图片描述

注册演示

在这里插入图片描述

填写正确邮箱号后,邮箱将接受到激活信息,点击激活信息,即可登录

登录成功演示

在这里插入图片描述

点击右上角气泡按钮,跳转到气泡页
在这里插入图片描述

项目实现

安装所需库

pip install pillowpip install django-simple-captchapip install django-simpleuipip install six

项目目录结构

项目名为loginproject,应用名为login

在这里插入图片描述

定义模型

  • login/models.py
from django.db import models# Create your models here.class User(models.Model):    gender=(        ('male','男'),        ('female','女'),    )    name=models.CharField(max_length=128,unique=True)    password=models.CharField(max_length=256)    email=models.EmailField(unique=True)    sex=models.CharField(max_length=32,choices=gender,default="男")    c_time=models.DateTimeField(auto_now_add=True)    #新增了has_confirmed字段,这是个布尔值,默认为False,也就是未进行邮件注册;    has_confirmed = models.BooleanField(default=False)    def __str__(self):        return self.name    class Meta:        ordering=["-c_time"]        verbose_name="用户"        verbose_name_plural="用户"class ConfirmString(models.Model):    '''    ConfirmString模型保存了用户和注册码之间的关系,一对一的形式;    '''    #code字段是哈希后的注册码;    code = models.CharField(max_length=256)    user = models.OneToOneField('User', on_delete=models.CASCADE, )    c_time = models.DateTimeField(auto_now_add=True)    def __str__(self):        return self.user.name + ":   " + self.code    class Meta:        ordering = ["-c_time"]        verbose_name = "确认码"        verbose_name_plural = "确认码"

配置settings.py文件

配置INSTALLED_APPS

INSTALLED_APPS = [    'login',  # 应用名    'simpleui',  # 后台美化    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'captcha',  # 图形验证码]

配置静态文件static路径

STATIC_URL = '/static/'STATICFILES_DIRS = [    os.path.join(BASE_DIR, "static","static"),]

配置模板文件路径

TEMPLATES = [    {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR,'static','templates')], # 添加模板文件路径 'APP_DIRS': True, 'OPTIONS': {
'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], 'builtins':['django.templatetags.static'], # 添加该行,不用在静态模板中,手动添加{% load static %} }, },]

配置邮箱SMTP设置

可自行百度如何开启163邮箱的POP3/SMTP服务

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'EMAIL_HOST = 'smtp.163.com'EMAIL_PORT = 25EMAIL_HOST_USER = '填入自己的163邮箱'EMAIL_HOST_PASSWORD = '开启163邮箱POP3/SMTP服务后的授权密码'# 注册有效期天数CONFIRM_DAYS = 7

注册模型字段到后台admin

  • login/admin.py
from django.contrib import adminfrom .models import *# Register your models here.class UserAdmin(admin.ModelAdmin):    list_display = ('name','sex','email','password','c_time')    list_filter = ['sex','name','c_time']    search_fields = ['sex','name','c_time']class ConfirmAdmin(admin.ModelAdmin):    list_display = ('code','user','c_time')admin.site.register(User,UserAdmin)admin.site.register(ConfirmString,ConfirmAdmin)

配置form表单

在应用下创建forms.py文件

  • login/forms.py
from django import formsfrom captcha.fields import CaptchaFieldclass UserForm(forms.Form):    username = forms.CharField(label="用户名", max_length=128, widget=forms.TextInput(attrs={
'class': 'form-control'})) password = forms.CharField(label="密码", max_length=256, widget=forms.PasswordInput(attrs={
'class': 'form-control'})) captcha = CaptchaField(label='验证码')class RegisterForm(forms.Form): gender = ( ('male', "男"), ('female', "女"), ) username = forms.CharField(label="用户名", max_length=128, widget=forms.TextInput(attrs={
'class': 'form-control'})) password1 = forms.CharField(label="密码", max_length=256, widget=forms.PasswordInput(attrs={
'class': 'form-control'})) password2 = forms.CharField(label="确认密码", max_length=256, widget=forms.PasswordInput(attrs={
'class': 'form-control'})) email = forms.EmailField(label="邮箱地址", widget=forms.EmailInput(attrs={
'class': 'form-control'})) sex = forms.ChoiceField(label='性别', choices=gender) captcha = CaptchaField(label='验证码')

数据库迁移

python manage.py makemigrationspython manage.py migrate

配置路由

设计应用路由

在应用下创建urls.py文件

  • login/urls.py
from django.conf.urls import urlfrom .views import *# CBV模式urlpatterns = [    url(r'^index/', IndexView.as_view(),name='index'),    url(r'^login/', LoginView.as_view(),name='login'),    url(r'^register/', RegisterView.as_view(),name='register'),    url(r'^logout/', LogoutView.as_view(),name='logout'),    url(r'^confirm/$', UserConfirmView.as_view(),name='confirm'),    url(r'^content/',  ContentView.as_view(),name='content'),]

配置根路由

与项目名同名的目录下的urls.py文件

  • loginproject/urls.py
from django.conf.urls import urlfrom django.conf.urls import includefrom django.contrib import adminurlpatterns = [    url(r'^admin/', admin.site.urls),    url(r'',include('login.urls')), # 配置app,login的url    url(r'^captcha', include('captcha.urls')),  # 配置图形验证码路由]

视图代码

  • login/views.py
import hashlibimport datetimefrom django.shortcuts import renderfrom django.shortcuts import redirectfrom . import modelsfrom django import formsfrom login import formsfrom django.conf import settingsfrom django.views.generic import Viewfrom functools import wrapsfrom django.utils.decorators import method_decoratorfrom django.core.mail import EmailMultiAlternatives# Create your views here.def hash_code(s, salt='mysite'):  # 加盐	# 加密    h = hashlib.sha256()    s += salt    h.update(s.encode())  # update方法只接收bytes类型    return h.hexdigest()def make_confirm_string(user):	# 激活确定    now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")    code = hash_code(user.name, now)    models.ConfirmString.objects.create(code=code, user=user,)    return codedef send_email(email, code):	# 邮箱发送    subject = '来自Mr Wolf的注册确认邮件'    text_content = '''感谢注册Mr Wolf,专注于Django实战的博客分享!\                    如果你看到这条消息,说明你的邮箱服务器不提供HTML链接功能,请联系管理员!'''    html_content = '''                    

感谢注册Mr Wolf系统,\ 专注于Django实战的博客分享!

请点击站点链接完成注册确认!

此链接有效期为{}天!

'''.format('127.0.0.1:8000', code, settings.CONFIRM_DAYS) msg = EmailMultiAlternatives(subject, text_content, settings.EMAIL_HOST_USER, [email]) msg.attach_alternative(html_content, "text/html") msg.send()# session认证装饰器def login_check(func): @wraps(func) def wrapper(request): if not request.session.get('is_login', None): return redirect("/login/") else: return func(request) return wrapper# CBV模式class IndexView(View): ''' 首页 ''' def get(self,request): return render(request, 'login/index.html')class RegisterView(View): ''' 注册 ''' def get(self,request): register_form = forms.RegisterForm(request.POST) return render(request, 'login/register.html', {
'message': '','register_form':register_form}) def post(self,request): register_form = forms.RegisterForm(request.POST) if register_form.is_valid(): # 获取数据 username = request.POST.get('username','') password1 = request.POST.get('password1','') password2 = request.POST.get('password2','') email = request.POST.get('email','') sex = request.POST.get('sex','') if password1 != password2: # 判断两次密码是否相同 message = "两次输入的密码不同!" return render(request, 'login/register.html', {
'message': message, 'register_form': register_form}) else: same_name_user = models.User.objects.filter(name=username) same_email_user = models.User.objects.filter(email=email) if same_name_user: # 用户名唯一 message = '用户已经存在,请重新选择用户名!' return render(request, 'login/register.html', {
'message': message, 'register_form': register_form}) elif same_email_user: # 邮箱地址唯一 message = '该邮箱地址已被注册,请使用别的邮箱!' return render(request, 'login/register.html', {
'message': message, 'register_form': register_form}) else: # 当一切都OK的情况下,创建新用户 new_user = models.User() new_user.name = username new_user.password = hash_code(password1) # 使用哈希加密密码 new_user.email = email new_user.sex = sex new_user.save() code = make_confirm_string(new_user) send_email(email, code) message = '请前往注册邮箱,进行邮件确认!' return render(request, 'login/confirm.html', {
'message': message}) # 跳转到等待邮件确认页面。class LoginView(View): ''' 登录 ''' def get(self,request): login_form = forms.UserForm(request.POST) return render(request,'login/login.html',{
'login_form':login_form}) def post(self,request): login_form = forms.UserForm(request.POST) message = "请检查填写的内容!" if login_form.is_valid(): username = request.POST.get('username','') password = request.POST.get('password','') try: user = models.User.objects.get(name=username) if not user.has_confirmed: message = "该用户还未通过邮件确认!" return render(request, 'login/login.html', {
'message': message,'login_form':login_form}) if user.password == hash_code(password): # 哈希值和数据库内的值进行比对 # 记录会话状态 request.session['is_login'] = True request.session['user_id'] = user.id request.session['user_name'] = user.name return redirect('/index/') else: message = "密码不正确!" except: message = "用户不存在!" return render(request, 'login/login.html', {
'message': message,'login_form':login_form})class LogoutView(View): ''' 退出 ''' def get(self,request): if not request.session.get('is_login', None): return redirect("/index/") request.session.flush() # 或者使用下面的方法 # del request.session['is_login'] # del request.session['user_id'] # del request.session['user_name'] return redirect("/index/")class UserConfirmView(View): ''' 邮箱激活认证 ''' def get(self,request): code = request.GET.get('code', None) try: confirm = models.ConfirmString.objects.get(code=code) except: message = '无效的确认请求!' return render(request, 'login/confirm.html', {
'message': message}) c_time = confirm.c_time now = datetime.datetime.now() if now > c_time + datetime.timedelta(settings.CONFIRM_DAYS): confirm.user.delete() message = '您的邮件已经过期!请重新注册!' return render(request, 'login/confirm.html', {
'message': message}) else: confirm.user.has_confirmed = True confirm.user.save() confirm.delete() message = '感谢确认,请使用账户登录!' login_form = forms.UserForm(request.POST) return render(request, 'login/login.html', {
'message': message, 'login_form': login_form})class ContentView(View): # 气泡页面视图,登录后才允许访问 @method_decorator(login_check) def get(self,request): message = '验证气泡显示' return render(request, 'content.html', {
'message': message})

前端实现

到上下载参考

转载地址:http://igugn.baihongyu.com/

你可能感兴趣的文章
spring 几种视图解析器
查看>>
spring 架包的说明
查看>>
web.xml引入 xml (tomcat 7.0.52) 以上版本报错!
查看>>
Ehcache 分布式缓存 -springMVC
查看>>
springMVC Spring MVC 异常处理
查看>>
解决MySQL不允许(其它IP)从远程访问的方法
查看>>
hibernaate 主键生成策略
查看>>
三个annotation类型(RetentionPolicy,ElementType)
查看>>
StringUtils用法 方法说明
查看>>
Spring @Resource、@Autowired、@Qualifier的注解注入及区别
查看>>
oracle创建表中LONG字段类型的使用注意事项
查看>>
Nginx+tomct 动静分离实现负载均衡
查看>>
Uploadify 3.2 参数属性、事件、方法函数详解以及配置
查看>>
uploadify 上传图片附件问题
查看>>
JSP文件是否有必要放在WEB-INF下
查看>>
springMVC + hibernate jar整合 (包含log4j)
查看>>
oracle 语句修改字段类型
查看>>
Java开发中的23种设计模式详解
查看>>
mybaties 多个参数传参的三种解决方案
查看>>
Java 内存模型及GC原理
查看>>