django中間件和auth模塊

Django中間件

 

 由django的生命週期圖咱們能夠看出,django的中間件就相似於django的保安,請求一個相應時要先經過中間件才能到達django後端(url、views、template、models),一樣後端進行響應的時候也須要通過中間件才能達到web服務網關。前端

django的七個中間件

MIDDLEWARE = [
                'django.middleware.security.SecurityMiddleware',
                #  一些安全設置,好比XSS腳本過濾

                'django.contrib.sessions.middleware.SessionMiddleware',
                #  session支持中間件,加入這個中間件,會在數據庫中生成一個django_session的表。
 
                'django.middleware.common.CommonMiddleware',
                #  通用中間件,會處理一些URL,好比baidu.com會自動的處理成www.baidu.com。好比/blog/111會處理成/blog/111/自動加上反斜槓。

                'django.middleware.csrf.CsrfViewMiddleware',
                 # 跨域請求僞造中間件。加入這個中間件,在提交表單的時候會必須加入csrf_token,cookie中也會生成一個名叫csrftoken的值,也會在header中加入一個HTTP_X_CSRFTOKEN的值來放置CSRF攻擊。

                'django.contrib.auth.middleware.AuthenticationMiddleware',
                #  用戶受權中間件。他會在每一個HttpRequest對象到達view以前添加當前登陸用戶的user屬性,也就是你能夠在view中經過request訪問user。

                'django.contrib.messages.middleware.MessageMiddleware',
                #  消息中間件。展現一些後臺信息給前端頁面。若是須要用到消息,還須要在INSTALLED_APPS中添加django.contrib.message纔能有效。若是不須要,能夠把這兩個都刪除。

                'django.middleware.clickjacking.XFrameOptionsMiddleware',
                #  防止經過瀏覽器頁面跨Frame出現clickjacking(欺騙點擊)攻擊出現。
            ]        

django中間的自定義方法

中間件能夠定義五個方法,分別是:(主要的是process_request和process_response)web

  • process_request(self,request)
  • process_view(self, request, view_func, view_args, view_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

自定義中間件的示例

 

 

 1.process_request()方法ajax

規律
  1.請求來的時候 會通過每一箇中間件裏面的process_request方法(從上往下)
  2.若是方法裏面直接返回了HttpResponse對象 那麼會直接返回 再也不往下執行
基於該特色就能夠作訪問頻率限制,身份校驗,權限校驗數據庫

2.process_response()方法django

規律
  1.必須將response形參返回 由於這個形參指代的就是要返回給前端的數據
  2.響應走的時候 會依次通過每個中間件裏面的process_response方法(從下往上)後端

3.process_view()方法跨域

  1.在路由匹配成功執行視圖函數以前 觸發瀏覽器

4.process_exception()方法安全

  1.當你的視圖函數報錯時  就會自動執行cookie

5.process_template_response()方法

  1.當你返回的HttpResponse對象中必須包含render屬性纔會觸發

def index(request):
    print('我是index視圖函數')
    def render():
        return HttpResponse('什麼鬼玩意')
    obj = HttpResponse('index')
    obj.render = render
    return obj

總結:以上方法的返回值能夠是None或一個HttpResponse對象,若是是None,則繼續按照django定義的規則向後繼續執行,若是是HttpResponse對象,則直接將該對象返回給用戶。

中間件的proce_request方法是在執行視圖函數以前執行的。

當配置多箇中間件時,會按照MIDDLEWARE中的註冊順序,也就是列表的索引值,從前到後依次執行的。

不一樣的中間件之間傳遞的request都是同一個對象。

若是須要本身寫的中間件生效,必須繼承MiddlewareMixin,並且要保證在註冊時路徑不能寫錯。

csrf跨站請求僞造

關於釣魚網站的原理,好比說你登陸了一個釣魚網站的頁面,和中國銀行如出一轍的頁面,你在哪裏進行轉帳操做,它的轉帳信息也確實發到了中國銀行,你的帳戶確實也扣錢了,可是惟一不對的時收款人不是你輸入的那我的,那是由於它在用戶輸入框的input上作了手腳,這個input沒有設置name屬性,而在內部,隱藏的標籤裏,有一個寫好了name和value的input框,這樣你只要點擊提交,那個value(釣魚網站受益人的帳戶)就會和你的轉帳信息一塊兒發給中國銀行。

防止釣魚網站的思路

網站會給返回給用戶的form表單頁面 偷偷塞一個隨機字符串
請求到來的時候 會先比對隨機字符串是否一致 若是不一致 直接拒絕(403)
該隨機字符串有如下特色
1.同一個瀏覽器每一次訪問都不同
2.不一樣瀏覽器絕對不會重複

經過{% csrf_token %}來生成隨機字符串

1.form表單發送post請求的時候  須要你作得僅僅書寫一句話

{% csrf_token %}

2.ajax發送post請求 如何避免csrf校驗

1.如今頁面上寫{% csrf_token %},利用標籤查找  獲取到該input鍵值信息
    {'username':'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()}
    $('[name=csrfmiddlewaretoken]').val()
    
2.直接書寫'{{ csrf_token }}'
    {'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}
    {{ csrf_token }}

3.你能夠將該獲取隨機鍵值對的方法 寫到一個js文件中,以後只須要導入該文件便可
    新建一個js文件 存放如下代碼 以後導入便可 
    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    var csrftoken = getCookie('csrftoken');


    function csrfSafeMethod(method) {
      // these HTTP methods do not require CSRF protection
      return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }

    $.ajaxSetup({
      beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
          xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
      }
    });

防釣魚的處理方法有了,當若是你的網站全局都須要校驗csrf的時候,又有幾個不須要校驗的該如何處理,相反若是你的網站全局不須要校驗csrf的時候,又有幾個須要校驗的功能又該怎麼處理。

#先導入模塊
from django.utils.decorators import method_decorator    
from django.views.decorators.csrf import csrf_exempt,csrf_protect

當整個網站都不校驗,只想某個功能校驗時

# 第一種方式
# @method_decorator(csrf_protect,name='post')  # 有效的
class MyView(View):
    # 第三種方式
    # @method_decorator(csrf_protect)
    def dispatch(self, request, *args, **kwargs):
        res = super().dispatch(request, *args, **kwargs)
        return res

    def get(self,request):
        return HttpResponse('get')
    # 第二種方式
    # @method_decorator(csrf_protect)  # 有效的
    def post(self,request):
        return HttpResponse('post')

當整個網站都校驗,只想某個功能不校驗時

#若是是csrf_exempt 只有兩種(只能給dispatch裝)   特例
@method_decorator(csrf_exempt,name='dispatch')  # 第二種能夠不校驗的方式
class MyView(View):
    # @method_decorator(csrf_exempt)  # 第一種能夠不校驗的方式
    def dispatch(self, request, *args, **kwargs):
        res = super().dispatch(request, *args, **kwargs)
        return res

    def get(self,request):
        return HttpResponse('get')

    def post(self,request):
        return HttpResponse('post')

總結:裝飾器中只有csrf_exempt是特例,其餘的裝飾器在給CBV裝飾的時候 均可以有三種方式

Auth模塊

一、Auth模塊是什麼

Auth模塊是Django自帶的用戶認證模塊:

咱們在開發一個網站的時候,無可避免的須要設計實現網站的用戶系統。此時咱們須要實現包括用戶註冊、用戶登陸、用戶認證、註銷、修改密碼等功能,這還真是個麻煩的事情呢。

Django做爲一個完美主義者的終極框架,固然也會想到用戶的這些痛點。它內置了強大的用戶認證系統--auth,它默認使用 auth_user 表來存儲用戶數據。

要注意的時,使用auth模塊的話最好用全套。

createsuperuser   #建立超級用戶 這個超級用戶就能夠擁有登錄django admin後臺管理的權限

auth模塊的功能

    #查詢用戶
        from django.contrib import auth
        user_obj = auth.authenticate(username=username,password=password)  # 必需要用 由於數據庫中的密碼字段是密文的 而你獲取的用戶輸入的是明文
    #記錄用戶狀態
        auth.login(request,user_obj)  # 將用戶狀態記錄到session中
    #判斷用戶是否登陸
        print(request.user.is_authenticated)  # 判斷用戶是否登陸  若是是大家用戶會返回False
    #用戶登陸以後 獲取用戶對象
        print(request.user)  # 若是沒有執行auth.login那麼拿到的是匿名用戶
    #校驗用戶是否登陸
        from django.contrib.auth.decorators import  login_required
        @login_required(login_url='/xxx/')  # 局部配置
        def index(request):
            pass
        
        # 全局配置  settings文件中
        LOGIN_URL = '/xxx/'
    #驗證密碼是否正確
        request.user.check_password(old_password)
    #修改密碼    
        request.user.set_password(new_password)
        request.user.save()  # 修改密碼的時候 必定要save保存 不然沒法生效
    #退出登錄
        auth.logout(request)  # request.session.flush()
    #註冊用戶
            # User.objects.create(username =username,password=password)  # #建立用戶名的時候 千萬不要再使用create 了
            # User.objects.create_user(username =username,password=password)  # 建立普通用戶
            User.objects.create_superuser(username =username,password=password,email='123@qq.com')  # 建立超級用戶  郵箱必填

自定義auth_user表

from django.contrib.auth.models import AbstractUser
# Create your models here.
# 第一種 使用一對一關係  不考慮

# 第二種方式   使用類的繼承
class Userinfo(AbstractUser):
    # 千萬不要跟原來表中的字段重複 只能創新
    phone = models.BigIntegerField()
    avatar = models.CharField(max_length=32)

# 必定要在配置文件中 告訴django
# 告訴django  orm再也不使用auth默認的表  而是使用你自定義的表
AUTH_USER_MODEL = 'app01.Userinfo'  # '應用名.類名'
"""
1.執行數據庫遷移命令
    全部的auth模塊功能 所有都基於你建立的表 
    而再也不使用auth_user
"""
相關文章
相關標籤/搜索