在有登录的系统中,有些页面可以不登录账户就可以访问,如:登录页、注册页等等,而有些网页则只能在登录成功之后才能跳转,如:个人信息主页,购物车页等等。 此时可以使用session记录登录状态来限制范围权限。 记录两种实现方法: ①在视图函数中,执行视图函数前,通过调用装饰器来获取session中的登录信息,判断是否登录成功,进而函数返回对应的页面。 ②使用中间件,在接收到客户端访问请求时,获取session记录的登录信息,并对比客户端请求访问的路由,判断是否执行,未登录且访问需登录的网页,直接中断执行返回登录页,否则正常执行视图函数。
本案例中 登录页(login.html)、注册页(register.html)、退出页(loginout.html)可随意访问, 首页(index.html)、详情页(detail.html)需登录后访问.
具体方法见: 二、实现方法
一、搭建项目
1、创建项目
1、创建django项目
django-admin startproject Xxxx
2、创建数据库
create database Xxxx character set utf8;
3、项目内导入静态文件
4、配置项目 settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'LoginCS',
'HOST': 'localhost',
'USER': 'root',
'PASSWORD': '123123',
'PORT': '3306'
}
}
STATICFILES_DIRS = [
(os.path.join(BASE_DIR,'static')),
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'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',
],
},
},
]
_ init _.py:
import pymysql
pymysql.install_as_MySQLdb()
2、创建应用
1、创建应用
python manage.py startapp Xxxx
2、注册应用 settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user',
]
3、创建模型
3、迁移文件
1、生成迁移文件
python manage.py makemigrations
2、迁移
python manage.py migrate
4、配置路由
settings.py文件同级目录中的urls.py文件:
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/',login),
url(r'^loginout/',loginout),
]
5、创建视图函数
views.py:
import hashlib
import re
from django.http import HttpResponseRedirect
from django.shortcuts import render
from user.models import logininfo
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
else:
uname = request.POST.get('use_rname')
pwd = request.POST.get('pdw')
cache = request.POST.get('cache')
if len(uname) < 5 or len(uname) > 20:
return render(request,'login.html',{'errMsg':'用户名必须在5-20个字符'})
elif len(pwd) < 8 or len(pwd) > 20:
return render(request,'login.html',{
'errMsg':'密码不符合规范,8-20个字符'
})
user = logininfo.objects.filter(username=uname)
if user:
sha1=hashlib.sha256()
sha1.update(pwd.encode('utf-8'))
sha1_pwd = sha1.hexdigest()
if user[0].pwd != sha1_pwd:
return render(request, 'login.html', {
'errMsg': '密码错误!'
})
else:
res = HttpResponseRedirect('/')
res.set_cookie('username',uname)
request.session['is_login'] = True
return res
else:
return render(request, 'login.html', {
'errMsg': '用户未注册!'
})
def register(request):
if request.method == 'GET':
return render(request, 'register.html')
else:
uname = request.POST.get('user_name')
pwd = request.POST.get('pwd')
confirmPwd = request.POST.get('cpwd')
email = request.POST.get('email')
allow = request.POST.get('allow')
if len(uname) < 5 or len(uname) > 20:
return render(request, 'register.html', {
'errMsg': '用户名必须在5-20个字符'
})
if len(pwd) < 8 or len(pwd) > 20:
return render(request, 'register.html', {
'errMsg': '密码不符合规范,8-20个字符'
})
if pwd != confirmPwd:
return render(request, 'register.html', {
'errMsg': '两次输入密码不一致'
})
if re.match('^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email) == None:
return render(request, 'register.html', {
'errMsg': '邮箱不符合规范'
})
if allow != 'on':
return render(request, 'register.html', {
'errMsg': '请同意网站协议'
})
user = logininfo.objects.filter(username=uname)
if user:
return render(request, 'register.html', {
'errMsg': '用户名已存在'
})
else:
newUser = logininfo()
newUser.username = uname
sha256 = hashlib.sha256()
sha256.update(pwd.encode('utf-8'))
sPwd = sha256.hexdigest()
newUser.password = sPwd
newUser.email = email
newUser.is_active = 0
newUser.save()
return HttpResponseRedirect('/login')
def loginout(request):
request.session.flush()
return render(request,'login.html')
def index(request):
return render(request, 'index.html')
def detail(request):
return render(request, 'detail.html')
二、实现方法
1、装饰器实现访问限制
1、views.py同级目录中创建装饰器文件zsq.py:
from django.http import HttpResponseRedirect
def a(func):
def inner(request):
is_login = request.session.get('is_login')
if is_login:
return func(request)
else:
return HttpResponseRedirect('/login')
return inner
2、views.py文件中引入装饰器并使用
from .zsq import a
@a
def index(request):
return render(request, 'index.html')
@a
def detail(request):
return render(request, 'detail.html')
此时浏览器直接访问 首页:http://127.0.0.1:8000/index/ 详情页:http://127.0.0.1:8000/detail/ 都将强制跳转到登录页面:http://127.0.0.1:8000/login/ 只有登录成功后才能访问。
2、中间件实现限制访问
1、创建中间件文件Middleware.py:
from django.http import HttpResponseRedirect
from django.utils.deprecation import MiddlewareMixin
whiteUrls = ['/login/','/register/','/loginout/','/admin/']
class UserAuthMiddleWare(MiddlewareMixin):
def process_request(self,request):
print(request.path)
if request.path not in whiteUrls and request.path.startswith('/admin') == False:
is_login = request.session.get('is_login',None)
if not is_login:
return HttpResponseRedirect('/login')
2、settings.py文件中注册创建的中间件:
MIDDLEWARE = [
。。。。。
'LoginCS.Middleware.UserAuthMiddleWare',
]
3、注释前面使用的装饰器
from .zsq import a
def index(request):
return render(request, 'index.html')
def detail(request):
return render(request, 'detail.html')
此时浏览器直接访问 首页:http://127.0.0.1:8000/index/ 详情页:http://127.0.0.1:8000/detail/ 都将强制跳转到登录页面:http://127.0.0.1:8000/login/ 只有登录成功后才能访问。
|