Web框架Danjgo之session cookie及认证组件

一 Cookie

1 什么是Cookie

Cookie翻译成中文是小饼干的意思。其实Cookie是key-value结构,类似于一个Python中的字典。随着服务器端的响应发送给客户端浏览器。
然后客户端浏览器会把Cookie保存起来,当下一次在再访问服务器时把Cookie在发送给服务器。Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对。
客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie)。当客户端向服务器发出请求是会把所有这个服务器Cookie包含在请求中几个发送给服务器,这样服务器就可以识别客户端了。

2 Cookie的规范

(1) Cookie大小上限为4kb
(2) 一个服务器最多在客户端浏览器保存20个Cookie
(3) 一个浏览器最多保存300个Cookie

3 代码中操作cookie

cookie相关参数

class HttpResponse:
	def set_cookie(self,key,	    键
		value='',		    值
		max_age=None		    超长时间,如果参数是None,这个cookie会延续到浏览器关闭为止。
		expires=None		    超长时间,expires默认是None,cookie失效的实际日期/时间。
		path='/'		    Cookie生效的路径,浏览器只会把cookie回传给带有路径的页面,这样可以避免将cookie传给站点中的其他的应用
		domian=None		    Cookie生效的域名, 你可以用这个来构造一个跨站cookie
		secure = False		    如果设置为True,浏览器将通过HTTPS来回传cookie
		httponly = False	    只能http协议传输,无法被JavaScript获取

设置cookie

1 respose = HttpResponse("登录成功")
2 respose.set_cookie("is_login", True)        # 向客户端返回cookie
3 return render(request,"login.html")

 取出cookie并进行验证

1 is_login = request.COOKIES.get("is_login")
2 if is_login:
3     return render(request,"index.html")
4 else:
5     return redirect("login")

删除cookie

1 respose.delete_cookie("cookie_key",path="/",domian=name)

设置cookie超时时间

1 respose.set_cookie("is_login",True,max_age=10)      # 10秒后超时
2 import datatime
3 timeout = datatime.datetime.utcnow() + datetime.timedelta(seconds=10)
4 response.set_cookie("username","harry" expires=timeout)         # 设置expire需要通过datetime设置

4 使用cookie验证此前是否登录成功

 1 def login(req):
 2     if req.method == 'POST':
 3         username = req.POST.get("user")
 4         pwd = req.POST.get("pwd")
 5         user = UserInfo.objects.filter(username=username,password=pwd).first()
 6         print(user)
 7         if user:
 8             response = HttpResponse("登录成功")
 9             response.set_cookie('is_login',True)
10             response.set_cookie('username', user.username)
11             return response
12     return render(req, "login.html")
13             
14 def index(req):
15     username = req.COOKIES.get('username')
16     is_login = req.COOKIES.get('is_login')
17     if is_login:
18             return render(req,'index.html', locals())
19 
20     return  redirect('/login/')

 使用cookie的两个示例

 1 def login(req):
 2     if req.method == 'POST':
 3             username = req.POST.get("user")
 4             pwd = req.POST.get("pwd")
 5             user = UserInfo.objects.filter(username=username,password=pwd).first()
 6             print(user)
 7         if user:
 8                 response = HttpResponse("登录成功")
 9                 response.set_cookie('is_login',True)
10                 response.set_cookie('username', user.username)
11                 return response
12     return render(req, "login.html")
保存上一次访问时间
 1 def show_goods(req):
 2         '''
 3         展示商品
 4         '''
 5         username = req.COOKIES.get('username')
 6         is_login = req.COOKIES.get('is_login')
 7         goods_obj = Goods.objects.all()
 8         return render(req,'shopping.html',locals())
 9 
10 def visit_goods(req, gid):
11         good_obj = Goods.objects.filter(id=gid).first()
12         visit_list = req.COOKIES.get('visit_goods')
13         response = render(req, 'item.html', locals())
14         if visit_list:
15             visit_list = (json.loads(visit_list))
16             visit_list.append(good_obj.name)
17             visit_list_json = json.dumps(visit_list)
18             response.set_cookie('visit_goods', visit_list_json)
19         else:
20             response.set_cookie('visit_goods', [])
21 
22         return response
23 
24 
25 def visit_history(req):
26         visited = req.COOKIES.get('visit_goods')
27         visited_list = json.loads(visited)
28         return render(req,'visit_history.html',locals())
显示上一次浏览过的商品

二 Session

Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,
所以用户在访问服务器web资源时, 可以把各自的数据放在各自的session中,当用户再去访问该浏览器的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务

1 django中session语法

 1 # 设置sessions值
 2     request.session{'seesion_name'} = "admin"
 3 # 获取sessions值
 4     session_name = request.session["session_name"]
 5 # 删除Session值
 6     del request.session["session_name"]
 7 # flush()
 8     删除当前的会话数据并删除会话的Cookie
 9     这个用于确保前面的会话数据不可以再次被用户浏览器访问
10 # 所有键,值,键值对
11     request.session.keys()
12     request.session.values()
13     request.session.items()
14     request.session.iterkeys()
15     request.session.itervalues()
16     request.session.iteritems()
17 # 用户session的随机字符串
18     request.session.session_key
19         
20 # 将有所Session的失效日期小于当前日期的数据删除
21     request.session.clear_expired()
22 # 检查用户session的随机字符串 在数据库中是否存在
23     reques.session.exists("session_key")
24 # 删除当前用户的所有Session数据
25     request.session.delete("session_key")

 2 session之保存登录状态信息

 1 def login_session(request):
 2         if request.method == "POST":
 3             user = request.POST.get("user")
 4             pwd = request.POST.get("pwd")
 5             username = UserInfo.objects.filter(user=user, pwd=pwd).first()
 6        
 7             if username:
 8                 request.session["is_login"] = True
 9                 request.session["username"] = "harry"
10                 '''
11                     注意:如果能读出来session_id 那么会进行一次更新操作
12                     1 生成随机字符串    234sd23asdjdasd
13                     2 respose.set_cookie("sessionod",234sd23asdj)
14                     3 在django-session表中创建一条记录:
15                             session-key        session-data
16                             234sd23asdj            {"is_login":True, "username":"harry"}
17                     '''
18                 return HttpResponse("登录成功")
19          return render(request,"login.html")
20             
21def index_session(request):
22        is_login = request.sessio.get("is_login")
23           '''
24            1  request.COOKIE.get("session")
25            2  django-session表中过滤记录
26            3  obj.session-data.get('is_login')
27          '''
28         if is_login:
29              return render(request,"index.html")
30         
31        return redirect("/login_session/")

3 session之注销用户

1 def logout(request)
2     request.sessio.flush()          # 删除当前对话数据并删除会话的cookie
3     return redirect("/login/")

 4 session配置选项

1 配置 settings.py
2         SESSION_COOKIE_NAME = "sessionid"          # Session的cookie保存在浏览器上时的keyt 即:sessionid=随机字符串(默认)
3         SESSION_COOKIE_PATH    = "/"               # Session的cookie保存的路径(默认)
4         SESSION_COOKIE_DOMAIN = None               # Session的cookie保存的域名(默认)
5         SESSION_COOKIE_SECURE = False              # 是否Https传输cookie(默认)
6         SESSION_COOKIE_HTTPONLY = True             # 是否session的cookie只支持http传输(默认)
7         SESSION_COOKIE_AGE = 1209600               # Session是cookie失效日期(2周) (默认)
8         SESSION_EXPIRE_AT_BROWSER_CLOSE = False    # 是否关闭浏览器使得Session过期(默认)
9         SESSION_SAVE_EVERY_REQUEST = False         # 每次请求都保存Session, 默认修改之后保存

三 Django提供的用户认证组件

用户认证组件:
功能:用session记录登录验证状态
前提:用户表dajango自带的auth_user

1 用户认证

auth模块
from django.contrib import auth
django.contrib.中提供了许多方法,这里主要介绍三种

(1) authenticate()


提供了用户认证,即验证用户名以及密码是否正确,一般需要username password两个关键字参数
如果认证消息有效,会返回一个User对象。authenticate()会在User对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程是需要的。
当我们试图登录一个从数据库中直接取过来不经过authenticate()的User对象会报错
user = authenticate(username='someone', password='somepassword')


(2) login(HttpRequest,user)
该函数接受一个HttpRequest对象,以及一个认证了的User对象
此函数使用django的session框架给某个已认证的用户附加上session id等信息

 1 from django.contrib.auth import authenticat,login
 2             
 3 def login(req):
 4       if req.method == "POST":
 5              user = req.POST.get("user")
 6              pwd = req.POST.get("pwd")
 7              # 如果验证成功返回user对象 否则返回None
 8              print(user,pwd)
 9              user = auth.authenticate(username=user, password=pwd)
10             if user:
11                  auth.login(req,user) # request.user=user 当前登录对象
12                  return HttpResponse('登录成功')
13        return render(req, "login.html")
14 
15 def index(req):
16 
17       print("request.user:", req.user.username)          # 用户对象,默认为空
18       print("request.user:", req.user.id)                # id默认是None
19       print("request.user:", req.user.is_anonymous)      # 是否是匿名用户
20 
21        if req.user.is_anonymous:
22              return redirect("/login/")
23 
24        eturn render(req, 'index.html', {"username":req.user.username})

(3) 注销功能

1 def logout(req):
2     auth.logout(req)
3     return redirect("/login/")

2 User对象

User对象属性:username password(必须填) password用哈希算法保存到数据库

(1) user对象的is_authenticate()
如果是真正的User对象,返回值恒为True。用于检查用户是否已经通过了认证。
通过认证并不意味着用户拥有任何权限,甚至不线程该用户是否处于激活状态,这只是表面成功通过了认证。
request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name

要求
1 用户登录号才能访问某些页面
2 如果用户没有登录就访问该页面的话直接跳到登录页面
3 用户在跳转的登录界面中完成验证后自动访问跳转到之前访问的地址

(2) 创建用户

使用create_user辅助函数创建用户
from django.contrib.auth.models import UserForm
user = User.objects.create_user (username='', password='', email='')

(3) 修改密码
使用set_password()来修改密码
user = User.objects.get(username='')
user.set_password(password='')
user.save

(4) 注册示例

1 def reg(request):
2      if request.method == "POST":
3       user = request.POST.get("user")
4       pwd = request.POST.get("pwd")
5       User.objects.create_user(username=user, password=pwd)
6       return render(request,"reg.html")

3 认证装饰器 login_requierd()

django为我们提供了一个login_requierd()的装饰器,这样就可以在有需要进行认证的视图函数中进行调用,以减少重复代码

from django.contrib.auth.decorators import login_requierd        
def login(req):
     if req.method == "POST":
          user = req.POST.get("user")
          pwd = req.POST.get("pwd")
          user = auth.authenticate(username=user, password=pwd)
          if user:
               auth.login(req,user) # request.user=user 当前登录对象
               next_url = req.GET.get("next")
               return redirect(next_url)
            return render(req, "login.html")

@login_requierd
def my_view(request):
            .....
        若用户没有登录,则会跳转到django默认的登录URL'/accounts/login/'(这个值可以在settings文件中通过LOGIN_URL进行修改)。并传递 当前访问url的绝对路径(登录成功后,会重新定向到该路径)
原文地址:https://www.cnblogs.com/harryblog/p/9361482.html