django测试平台开发,登录,验证,退出

#验证登录传递的数据是否符合规则,forms

### forms.py ###

# 不能用ModelForm
# 登录要验证什么? username password

class
LoginForm(forms.Form,tools.ErrorFormat): #ErrorFormat--优化error返回的错误信息 '''登陆验证username,password''' username = forms.CharField(min_length=5,max_length=20,required=True) password = forms.CharField(min_length=6,max_length=20,required=True) def clean(self): print("self.errors",self.errors) print("self.cleaned_data",self.cleaned_data) if not self.errors: #继续验证账号密码是否正确 username = self.cleaned_data['username'] password = self.cleaned_data['password'] #用户是否存在 qs = models.User.objects.filter(phone=username) if qs: user_obj = qs.first() if user_obj.check_password(password): self.cleaned_data['user'] =user_obj return self.cleaned_data else: self.add_error('password', '密码错误') else: self.add_error('username','用户不存在') return self.cleaned_data



##### tools.py ###
class ErrorFormat:
@property
def error_format(self):
errors_data = self.errors.get_json_data()
print("errors_data",errors_data)
error_list = []
for k,v in errors_data.items():
error_list.append(k+':'+v[0].get("message"))
return ','.join(error_list)

#2-views中写接口逻辑,连接并写入redis

class Login(View):
    def post(self, request):
        '''
        1、验证前端传递的数据是否符合规则,forms
        2、登录成功需要有标示,标示(token)存到  redis
        :param request:
        :return:
        '''
        form_obj = forms.LoginForm(request.POST)
        if form_obj.is_valid():
            # 验证通过的数据 代表登录成功
            # 登录成功需要有标示,标示(token)存到  redis
            form_data = form_obj.cleaned_data
            # token 生成方式  用户名 + 时间戳 + MD5
            username = form_data.get('username')
            tmp_token = '%s%s' % (username, time.time())
            # md5 用 tools提供工具
            token = tools.md5(tmp_token)
            # 存 token的时候  token 应该key
            user = form_obj.cleaned_data['user']
            # 安装 pip install django-redis
            # 获取redis 链接 默认取配置文件中 default
            redis = django_redis.get_redis_connection()
            # 参数1  是key  参数2 是value  参数3 是过期时间 单位秒
            # {token:userobj}
            #  pickle.dumps(user) 序列化数据,转成 二进制
            redis.set(const.SESSION + token, pickle.dumps(user), const.EXIT_TIME)
            return NbResponse(token=token, user=user.name, user_id=user.id)
        else:
            return NbResponse(-1, form_obj.error_format)


### redis配置,setting###
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100},
"PASSWORD": "dsx", # 密码
# 这个redis是返回数据是bytes类型的,登录的时候userpickle序列化的,存的是二进制,取出来的也是二进制
}
},
"redis2": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://118.24.3.40:6379/2",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100, 'decode_responses': True},
# 这个redis配置,从redis里面取到数据后会自动转成字符串,不是bytes类型
"PASSWORD": "HK139bc&*", # 密码
}

}
}

#3-NbResponse对响应数据封装 ,等同于重写JsonResponse

from django.http import JsonResponse

class NbResponse(JsonResponse):
    def __init__(self, code=200, msg='操作成功', **kwargs):
        data = {"code": code, "msg": msg}
        data.update(kwargs)
        super().__init__(data=data, json_dumps_params={"ensure_ascii": False})

#4-ursl配置

### 其它接口登录校验token,中间件


class
SessionMiddleware(MiddlewareMixin): # 增加 一个过滤的场景 # 预制一个 列表 列表用于存储,那些接口可以不登录就访问 setting中 :NO_LOGIN_LIST = ['login','register'] def check_url(self, path_info): for url in NO_LOGIN_LIST: # path_info 前端过来的路径 /api/login # url NO_LOGIN_LIST login if url in path_info: # 当前访问的接口路径 在 NO_LOGIN_LIST 返回false 不做token验证 return False return True def process_request(self, request): '''请求过来之后先走到的这里''' # print("dir(request)",dir(request)) # 前端传递过来的token 会自动变成大写,并且在前面增加HTTP # print("request.META.get('HTTP_TOKEN')",request.META.get('HTTP_TOKEN')) print('request.path_info', request.path_info) if self.check_url(request.path_info): token = request.META.get('HTTP_TOKEN') if token: redis = django_redis.get_redis_connection() b_data = redis.get(const.SESSION + token) if b_data: data = pickle.loads(b_data) # 将当前的登录信息 存储到request当中 request.user = data request.user_id = data.id request.token = token else: return NbResponse(-1, '请登录') else: return NbResponse(-1, '请登录')

##登出,删除token

class Logout(View):
    def post(self, request):
        redis = django_redis.get_redis_connection()
        redis.delete(const.SESSION + request.token)
        return NbResponse()
原文地址:https://www.cnblogs.com/whcp855/p/13667435.html