Django 搭建博客项目(三)

要点:
1、JWT
先要安装pyjwt,然后import jwt
jwt分为三部分:头、负载、签名
头部由加密算法构成,负载就是传输的信息,比如时间、用户的id,签名是用前两者用base64编码后再使用加密算法用密钥计算,并再次base64编码后的结果。 头、负载、签名之间用.号链接,头部和负载都要base64。
jwt主要用于防篡改,并不能隐藏信息(由于base64是公开的加密算法)
注册或者登陆后,颁发jwt 存放在cookie中。
jwt的缺点是 1、 不加密,不安全 2、一旦签发一直有效(所以要设置expire)
2、密码
防止暴力破解的办法:1、加验证码 2、使用慢哈希算法bcrypt :随机加盐、单向散列3、多次错误拒绝访问
3、Django ORM 对象关系模型
对象:增加、修改、删除、查询
SQL : insert、update、delete、select
查询集:
1、惰性求值 ,创建查询集不会访问数据库,除非调用方法使用数据。if语句,迭代,序列化都会访问数据库。
2、缓存,对查询集首次求值,Django会把结果缓存。
3、切片,qs = User.objects.all()[20:40] 相当于 LIMIT 20 OFFSET 20 ,依然是惰性求值。
返回查询集的方法称为过滤器:
all() 、 filter()、exclude()、values()#返回一个对象字典的列表,字典内是字段和值的键值对。
filter(pk=v1).filter(k2=v2) 等价于filter(pk=v1,k2=v2) #pk表示主键 primary key

返回单值的方法:
get() ,如果没get到 会抛出异常,有多个值也会抛出异常
count() ,返回查询总条数
first() 返回第一个对象 同理还有last()
exist() 是否存在

字段查询(Field Lookup) 表达式:字段名__比较运算符=值
可以作为 filter、get、exclude 的参数,用来实现where子句。
比如:filter(title__startswith=’‘天’’)
filter(id__in = [1,2,3,4])
filter(number__lte=6)
filter(pub_date__year=2000)
contain\ exact\startswith\endswith 前面可以加i 表示忽略大小写。
除了字段查询表达式,还有Q对象可以操作。Q对象可以使用and & 、or| 、not ~
例如 filter(Q(pk__gt = 6)& Q(pk__lt=10)) \ filter(~Q(pk__lt=6))

from django.conf import settings
import jwt
import datetime
import simplejson
from django.http import HttpResponse, HttpRequest, JsonResponse,HttpResponseBadRequest
from .models import  User
import bcrypt
SECRET_KEY = 'yuv#ss5sz-$dp36!@stf8@7@w$e30bm2#)9jpi9bg0gh+sdoz#'
AUTH_EXPIRE = 8*60*60

def authenticate(view):#认证装饰器
    def wrapper(request:HttpRequest):
        payload = request.META.get('HTTP_JWT')
        print(payload)
        if not payload:#如果META里面没有jwt,payload就为空,那么返回401
            return HttpResponse(status=401)
        try:
            payload = jwt.decode(payload,settings.SECRET_KEY,algorithms= ['HS256'])
            print(payload)
        except Exception as e:
            print(e)
            return HttpResponse(status = 401)

        current = datetime.datetime.now().timestamp()
        if (current - payload.get('timestamp',0))> AUTH_EXPIRE:#查看jwt是否过期,如果过期也返回401
            return HttpResponse(status=401)
        try:
            user_id = payload.get('user_id',-1)
            user = User.objects.filter(pk=user_id).get()
            request.user = user_id
            print('-' * 30)
        except Exception as e:
            print(e)
            return HttpResponse(status=401)
        ret = view(request)
        return ret
    return  wrapper

def gen_token(user_id):#用用户id、时间戳、密钥 来生成jwt token
    target =  jwt.encode({
        'user_id':user_id,
        'timestamp':int(datetime.datetime.now().timestamp())
    },settings.SECRET_KEY,'HS256').decode()#字符串
    return target

def reg(request:HttpRequest):#注册函数
    print('reg is running')
    payload = simplejson.loads(request.body)#用户用POST方法发来邮箱密码
    try:
        email = payload['email']
        query = User.objects.filter(email=email)#查询email是否已存在
        if query.first():#如果已存在 直接返回Badrequest
            return HttpResponseBadRequest()
        name = payload['name']

        password = bcrypt.hashpw(payload['password'].encode(),bcrypt.gensalt(),)#密码通过bcrypt 加密后存入数据库。

        user = User()
        user.name = name
        user.email = email
        user.password = password
        try:
            user.save()
            print('save is ok ')
            return JsonResponse({'token':gen_token(user.id)})#如果保存成功,返回jwt令牌
        except:
            return HttpResponseBadRequest()
    except:
        print('wrong')
        return HttpResponseBadRequest()



def login(request:HttpRequest):#登录功能函数
    payload = simplejson.loads(request.body)
    try:
        email = payload['email']
        user = User.objects.filter(email=email).get()

        if bcrypt.checkpw(payload['password'].encode(),user.password.encode()):#bcrypt.checkpw 用于比较 用户的密码和数据库中的密码是否一致
            token = gen_token(user.id)#如果密码一致,则生成token
            res = JsonResponse({'user':{'user_id':user.id,
                                        'name':user.name,
                                        'email':user.email,
                                        },'token':token})
            res.set_cookie('jwt',token) #返回用户id 、name、email 以及token 并设置cookies
            return res
        else:
            print(payload)
            return HttpResponseBadRequest()
    except:
        print(payload)
        return HttpResponseBadRequest()

你可能感兴趣的:(后端,django,后端,python)