1. 程式人生 > 實用技巧 >django測試平臺開發,登入,驗證,退出

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()