Python中的CSRF攻击与JWT令牌验证

2023-04-17 00:00:00 令牌 验证 攻击

CSRF攻击是指跨站请求伪造攻击,攻击者通过在受害者浏览器中植入恶意代码或链接,诱导受害者点击链接或访问网页,从而在受害者浏览器中执行非法操作。攻击者利用受害者的登录凭据来进行一些危险的操作,比如修改用户信息、删除数据等。

为了防止CSRF攻击,通常使用CSRF Token来验证请求是否合法。在Django中,在Post请求中携带csrfmiddlewaretoken参数,就可以在后端验证请求的合法性。实际上,Django已经将CSRF Token集成到了表单中。

下面是一个Django视图函数的例子,演示了如何使用Django自带的CSRF Token来防止CSRF攻击。

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

@csrf_protect
def csrf_demo(request):
    if request.method == 'POST':
        return HttpResponse('提交成功')
    return render(request, 'csrf_demo.html')

在HTML模板中,需要添加{% csrf_token %}标签,将CSRF Token嵌入表单中。

<form method="POST">
    {% csrf_token %}
    <input type="text" name="username">
    <input type="password" name="password">
    <button type="submit">提交</button>
</form>

JWT令牌验证是一种无状态的认证机制,使用JSON Web Token(JWT)来实现身份验证和数据的安全传输。JWT令牌由三部分组成:头部、载荷和签名。头部部分用于描述使用的算法(通常为HMAC SHA256或RSA),载荷部分是一个包含用户信息的JSON对象,签名部分是对头部和载荷部分的签名。

使用JWT令牌验证需要在后端实现一个视图函数来生成JWT Token,将Token添加到用户登录的响应中。在每个需要身份验证的请求中,将JWT Token作为Authorization头部的Bearer字段发送到服务器端进行验证,验证成功后则可以进行相应的操作。

下面是一个Django视图函数的例子,演示了如何使用JWT令牌验证。

import jwt
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response

class LoginView(APIView):
    def post(self, request):
        username = request.data.get('username', '')
        password = request.data.get('password', '')

        # 进行用户名和密码的验证
        user = User.objects.filter(username=username, password=password).first()
        if not user:
            return Response({'code': 400, 'msg': '用户名或密码错误'})

        # 生成JWT Token
        payload = {'user_id': user.id}
        token = jwt.encode(payload, 'secret', algorithm='HS256')

        # 返回响应
        return Response({'code': 200, 'msg': '登录成功', 'token': token.decode('utf-8')})

class UserInfoView(APIView):
    def get(self, request):
        # 获取Authorization头部的token
        authorization = request.META.get('HTTP_AUTHORIZATION', '')
        if not authorization.startswith('Bearer '):
            return Response({'code': 400, 'msg': '身份验证失败'})
        token = authorization.split(' ')[1]

        # 验证JWT Token
        try:
            payload = jwt.decode(token, 'secret', algorithms=['HS256'])
        except jwt.DecodeError:
            return Response({'code': 400, 'msg': '身份验证失败'})
        user_id = payload['user_id']

        # 查询用户信息
        user = User.objects.filter(id=user_id).first()
        if not user:
            return Response({'code': 400, 'msg': '用户不存在'})

        # 返回用户信息
        return Response({'code': 200, 'msg': '查询成功', 'username': user.username, 'email': user.email})

在JavaScript中,我们可以使用jsonwebtoken库来生成和验证JWT Token。下面是一个生成Token的例子。

import jwt from 'jsonwebtoken';

const payload = {username: 'pidancode.com', email: 'pidancode@example.com'};
const secret = 'my-secret';
const token = jwt.sign(payload, secret);

下面是一个验证Token的例子。

import jwt from 'jsonwebtoken';

const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InBpZGFuY29kZS5jb20iLCJlbWFpbCI6InBpZGFuY29kZUBleGFtcGxlLmNvbSIsImlhdCI6MTYyNzg0MTAwMCwiZXhwIjoxNjI3ODQ0NjAwfQ.W5x5Gqqy5rrOYL3ykL1gQYZzSfJQZwwBDnX9oGPIFY4';
const secret = 'my-secret';

jwt.verify(token, secret, (err, decoded) => {
  if (err) {
    console.error(err.message);
  } else {
    console.log(decoded);
  }
});

相关文章