1. 程式人生 > 其它 >為什麼Git遠端倉庫中要配置公鑰?

為什麼Git遠端倉庫中要配置公鑰?

目錄

csrf跨站請求偽造

1、前戲

"""
釣魚網站
	搭建一個跟正規網站一摸一樣的介面(中國銀行)
	使用者進入到我們的網站,使用者給某人打錢,
	使用者打錢操作確確實實是提交給了中國銀行的系統,使用者的錢也確確實實減少了,但是唯一不同是打錢的賬戶不是使用者想要打的賬戶,變成了另一個賬戶

內部本質:
	在釣魚網站的頁面,針對對方賬戶,只給使用者提供一個沒有name屬性的input框,然後我們再內部隱藏一個已經寫好name和value的input框,
		
"""
  • 真正的網站埠:8000

http://127.0.0.1:8000

# 註釋掉csrf
 'django.middleware.csrf.CsrfViewMiddleware',
<body>
<h1>中國銀行</h1>
<form action="" method="post">
    <p>username:<input type="text" name="username"></p>
    <p>target_user:<input type="text" name="target_user"></p>
    <p>money:<input type="text" name="money"></p>
    <input type="submit">
</form>
</body>
# views.py
def transfer(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        target_user = request.POST.get('target_user')
        money = request.POST.get('money')
        print('%s給%s轉了%s元' % (username, target_user, money))

    return render(request, 'transfer.html')

# urls.py
path('transfer/',views.transfer)
  • 釣魚網站模擬埠:8001
#不用註釋csfr
<body>
<h1>phishing site</h1>
<form action="http://127.0.0.1:8000/transfer/" method="post">
    <p>username:<input type="text" name="username"></p>
    <p>target_user:<input type="text"></p>
    <input type="text" name="target_user" value="zhao" style="display: none">
    <p>money:<input type="text" name="money"></p>
    <input type="submit">
</form>
</body>
#views.py
def transfer(request):
    return render(request,'transfer.html')

# urls.py
path('transfer/',views.transfer)

2、csrf校驗

如何規避上述問題:
csrf跨站請求偽造
網站再給使用者返回一個提交資料功能的頁面的時候會給這個頁面加一個唯一標識
當這個頁面朝後端發post請求的時候,後端會先校驗唯一標識,如果唯一標識不對,直接拒絕(403 forbiden),如果成功則正常執行

2.1、from表單如何符合校驗

#開啟配置檔案裡的csrf中介軟體
<form action="" method="post">
    {% csrf_token %}
    <p>username:<input type="text" name="username"></p>
    <p>target_user:<input type="text" name="target_user"></p>
    <p>money:<input type="text" name="money"></p>
    <input type="submit">
</form>

再次傳送請求

釣魚網站再次傳送請求

2.2、ajax如何符合校驗

不論是ajax還是誰,只要是向我Django提交post請求的資料,都必須校驗csrf_token來防偽跨站請求

  • 方式一

通過獲取隱藏的input標籤中的csrfmiddlewaretoken值,放置在data中傳送

</head>
<body>
<h1>中國銀行</h1>
<form action="" method="post">
    {% csrf_token %}
    <p>username:<input type="text" name="username"></p>
    <p>target_user:<input type="text" name="target_user"></p>
    <p>money:<input type="text" name="money"></p>
    <input type="submit">
</form>
<button id="d1">ajax請求</button>
</body>


<script>
    $('#d1').on('click', function () {
        $.ajax({
            url: '',
            type: 'post',
            //第一種:利用標籤查詢獲取頁面上的隨機字串
            data: {'username': 'zhao', 'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val()},
            success() {

            }

        })

    })
</script>
  • 方式二
</head>
<body>
<h1>中國銀行</h1>
<form action="" method="post">
    {% csrf_token %}
    <p>username:<input type="text" name="username"></p>
    <p>target_user:<input type="text" name="target_user"></p>
    <p>money:<input type="text" name="money"></p>
    <input type="submit">
</form>
<button id="d1">ajax請求</button>
</body>

<script>
    $('#d1').on('click', function () {
        $.ajax({
            url: '',
            type: 'post',
            //第二種方式:利用模板語法快捷書寫
            data: {'username': 'zhao', 'csrfmiddlewaretoken': '{{csrf_token}}'},
            }
        })
    })
</script>
  • 方式三

先拷貝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);
        }
    }
});

將檔案配置到靜態檔案中,在html頁面上通過匯入該檔案即可自動幫我們解決ajax提交post資料時校驗csrf_token的問題

</head>
<body>
<h1>中國銀行</h1>
<form action="" method="post">
    {% csrf_token %}
    <p>username:<input type="text" name="username"></p>
    <p>target_user:<input type="text" name="target_user"></p>
    <p>money:<input type="text" name="money"></p>
    <input type="submit">
</form>
<button id="d1">ajax請求</button>
</body>


{% load static %}
<script src="{% static  'js/setup.js' %}"></script>
<script>
    $('#d1').on('click', function () {
        $.ajax({
            url: '',
            type: 'post',
            //第三種方式:引入js檔案
            data: {'username': 'zhao'},
            success() {

            }

        })

    })
</script>

3、csrf相關裝飾器

3.1、FBV

  • 網站整體都校驗csrf,就單單幾個檢視函式不校驗
#配置檔案中開始csrf中介軟體,
from django.views.decorators.csrf import csrf_protect, csrf_exempt

"""
csrf_protect,需要校驗
csrf_exempt  忽視校驗
"""

@csrf_exempt 
def transfer(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        target_user = request.POST.get('target_user')
        money = request.POST.get('money')
        print('%s給%s轉了%s元' % (username, target_user, money))

    return render(request, 'transfer.html')
  • 網站整體都不校驗csrf,就單單幾個檢視函式需要校驗
# 註釋掉form表單中 {% csrf_token %}#}
#關閉配置檔案中csrf中介軟體

@csrf_protect
def transfer(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        target_user = request.POST.get('target_user')
        money = request.POST.get('money')
        print('%s給%s轉了%s元' % (username, target_user, money))

    return render(request, 'transfer.html')

3.2、CBV

csrf_protect,需要校驗
​	針對csrf_protect符合CBV裝飾器的三種寫法

csrf_exempt  忽視校驗
​	針對csrf_protect只能給dispatch方法加才有效
  • 網站整體都不校驗csrf,就單單幾個檢視函式需要校驗
# views.py
from django.utils.decorators import method_decorator
from django.views import View


# @method_decorator(csrf_protect,name='post') #第二種
class MycsrfToken(View):
    @method_decorator(csrf_protect)
    def dispatch(self, request, *args, **kwargs):
        return super(MycsrfToken, self).dispatch(request, *args, **kwargs)

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

    # @method_decorator(csrf_protect) #第一種方式可以
    def post(self, request):
        return HttpResponse('post')
    
    
# urls.py
 path('csrf/', views.MycsrfToken.as_view()),
# html  from表單向csrf路由提交
<h1>中國銀行</h1>
<form action="/csrf/" method="post">
{#    {% csrf_token %}#}
    <p>username:<input type="text" name="username"></p>
    <p>target_user:<input type="text" name="target_user"></p>
    <p>money:<input type="text" name="money"></p>
    <input type="submit">
</form>


    
# urls.py
path('transfer/', views.transfer),

# views.py
def transfer(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        target_user = request.POST.get('target_user')
        money = request.POST.get('money')
        print('%s給%s轉了%s元' % (username, target_user, money))

    return render(request, 'transfer.html')
  • 網站整體都校驗csrf,就單單幾個檢視函式不校驗
from django.utils.decorators import method_decorator
from django.views import View



# @method_decorator(csrf_exempt,name='dispatch') 
class MycsrfToken(View):

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

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

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