1. 程式人生 > 其它 >csrf跨站請求偽造;auth模組

csrf跨站請求偽造;auth模組

csrf跨站請求偽造

針對csrf相關的校驗有很多種方式,django只是提供了一些而已

form表單

前提必須是前後端整合,能夠使用模板語法

<form action="" method="post">
    {% csrf_token %}
    <p>當前賬戶:<input type="text" name="current_user"></p>
    <p>目標賬戶:<input type="text" name="target_user"></p>
    <p>轉賬金額:<input type="text" name="money"></p>
    <input type="submit">
</form>

ajax請求

方式1

頁面任意位置先寫{% csrf_token %} 之後獲取資料 

方式2

模板語法直接獲取

js指令碼自動處理

只能適用於ajax提交,form表單還是需要額外指定,直接cv拷貝

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_exempt:忽略csrf校驗;csrf_protect:開啟csrf校驗

from django.views.decorators.csrf import csrf_exempt,csrf_protect

針對FBV

# @csrf_exempt
# @csrf_protect
def login(request):
    return render(request, 'login.html')

針對CBV

from django import views
from django.utils.decorators import method_decorator

# @method_decorator(csrf_protect, name='post') # 可以校驗
# @method_decorator(csrf_exempt, name='post')
class MyView(views.View):
    # @method_decorator(csrf_protect) # 可以校驗
    def dispatch(self, request, *args, **kwargs):
        super(MyView, self).dispatch(request, *args, **kwargs)
    
    # @method_decorator(csrf_protect) # 可以校驗
    # @method_decorator(csrf_exempt) # 無效
    def post(self, request):
        return HttpResponse('from MyView post')

csrf_protect:三種CBV新增裝飾器的方式都可以

csrf_exempt:只有一種方式可以生效(重寫的dispatch方法)

@method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(MyView, self).dispatch(request, *args, **kwargs)

auth模組

概念

auth模組是django提供給你快速完成使用者相關功能的模組

django也配套提供了一張'使用者表':執行資料庫遷移命令之後預設產生的auth_user

django自帶的admin後臺管理使用者登入參考的就是auth_user表

建立admin後臺管理員使用者:createsuperuser

自動對使用者密碼進行加密處理並儲存

模組方法

from django.contrib import auth
  • 驗證使用者名稱和密碼是否正確
    auth.authenticate()
  • 儲存使用者登入狀態
    auth.login()
def lg(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        is_user_obj = auth.authenticate(request, username=username, password=password)
        # res = auth.authenticate(request, username=username, password=password)
        # print(res)  # 校驗正確返回的是使用者物件,錯誤返回的是None
        if is_user_obj:
            # 記錄使用者登入狀態
            auth.login(request, is_user_obj)
    return render(request, 'lg.html')
  • 獲取當前使用者物件
    request.user # session刪除掉會返回匿名使用者
  • 判斷當前使用者是否登入
    request.user.is_authenticated() # 返回布林值
  • 校驗登入裝飾器
    from django.contrib.auth.decorators import login_required
        # 區域性配置
        @login_required(login_url='/lg/')  
        # 全域性配置
        @login_required  
        LOGIN_URL = '/lg/'  # 需要在配置檔案中新增配置
  • 修改密碼
     if request.method == 'POST':
            old_password = request.POST.get('old_password')
            new_password = request.POST.get('new_password')
            # 先比對原密碼是否正確
            is_right = request.user.check_password(old_password)
            if is_right:
                # 修改密碼
                request.user.set_password(new_password) # 臨時修改密碼
                # 儲存資料
                request.user.save() # 修改操作同步到資料庫
  • 登出登入
    auth.logout(request)
  • 註冊使用者
    from django.contrib.auth.models import User
    def register(request):
        # User.objects.create(username='chen', password='111') # 不能使用create,密碼不會加密
        # User.objects.create_user(username='jame', password='111')
        User.objects.create_superuser(username='kurry', password='1111', email='[email protected]')
        return HttpResponse('註冊成功')

擴充套件表字段

方式1

編寫一對一表關係(瞭解)

方式2

類繼承(推薦)

from django.contrib.auth.models import AbstractUser
class Users(AbstractUser):
    # 編寫AbstractUser類中沒有的欄位 不能衝突!!!
    phone = models.BigIntegerField()
    addr = models.CharField(max_length=32)

配置檔案

AUTH_USER_MODEL = 'app01.Users'

注意

類繼承之後,需要重新執行資料庫遷移命令,並且庫裡面是第一次操作才可以

auth模組所有的方法都可以直接在自定義模型類上面使用

自動切換參照表