def post(self, request): """美多商城用户绑定到openid""" # 接收参数 mobile = request.POST.get('mobile') password = request.POST.get('password') sms_code_client = request.POST.get('sms_code') access_token_openid = request.POST.get('access_token_openid') # 校验参数 # 判断参数是否齐全 if not all([mobile, password, sms_code_client]): return http.HttpResponseForbidden('缺少必传参数') # 判断手机号是否合法 if not re.match(r'^1[3-9]\d{9}$', mobile): return http.HttpResponseForbidden('请输入正确的手机号码') # 判断密码是否合格 if not re.match(r'^[0-9A-Za-z]{8,20}$', password): return http.HttpResponseForbidden('请输入8-20位的密码') # 判断短信验证码是否一致 redis_conn = get_redis_connection('verify_code') sms_code_server = redis_conn.get('sms_%s' % mobile) if sms_code_server is None: return render(request, 'oauth_callback.html', {'sms_code_errmsg': '无效的短信验证码'}) if sms_code_client != sms_code_server.decode(): return render(request, 'oauth_callback.html', {'sms_code_errmsg': '输入短信验证码有误'}) # 判断openid是否有效:错误提示放在sms_code_errmsg位置 openid = check_access_token(access_token_openid) if not openid: return render(request, 'oauth_callback.html', {'openid_errmsg': '无效的openid'}) # 保存注册数据 try: user = User.objects.get(mobile=mobile) except User.DoesNotExist: # 用户不存在,新建用户 user = User.objects.create_user(username='******' + mobile, password=password, mobile=mobile) else: # 如果用户存在,检查用户密码 if not user.check_password(password): return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'}) # 将用户绑定openid try: OAuthQQUser.objects.create(openid=openid, user=user) except DatabaseError: return render(request, 'oauth_callback.html', {'qq_login_errmsg': 'QQ登录失败'}) # 实现状态保持 login(request, user) # 响应绑定结果 next = request.GET.get('state') response = redirect(next) # 登录时用户名写入到cookie,有效期15天 response.set_cookie('username', user.username, max_age=3600 * 24 * 15) # 若用户登录成功,合并cookie中的购物车 merge_carts_cookies_redis(request=request, user=user, response=response) return response
def post(self, request): # 接收参数 # login_form = LoginForm(request.POST) login_form = LoginForm(request.POST) if login_form.is_valid(): username = login_form.cleaned_data.get('username') password = login_form.cleaned_data.get('password') remembered = login_form.cleaned_data.get('remembered') if not all([username, password]): return HttpResponseForbidden('缺少必传参数') # 认证登录用户 # user = User.objects.get(username=username) # pwd = user.password # 密文 # user.check_password() # if check_password(password, pwd): # print('密码正确') # else: # print('密码错误') user = authenticate(username=username, password=password) # print(user) if user is None: return render(request, 'login.html', {'account_errmsg': '账号或密码错误'}) # 状态保持 login(request, user) if remembered != True: # 没有记住登录 浏览器关闭就销毁 request.session.set_expiry(0) else: # 记住登录 状态保持默认为2周 request.session.set_expiry(None) next = request.GET.get('next') if next: response = redirect(next) # return redirect(next) else: response = redirect(reverse('contents:index')) # 将用户名设置到cookie中 # 响应结果 重定向到首页; # return redirect(reverse('content:index')) # response = redirect(reverse('content:index')) response.set_cookie('username', user.username, max_age=3600) # 登陆成功后合并购物车 from carts.utils import merge_carts_cookies_redis merge_carts_cookies_redis(request, user, response) return response else: # print(login_form.errors) # print(login_form.errors.get_json_data()) context = {'forms_errors': login_form.errors} return render(request, 'login.html', context=context)
def post(self, request): """实现用户登录逻辑""" # 接收参数 username = request.POST.get('username') password = request.POST.get('password') remembered = request.POST.get('remembered') # 校验参数 if not all([username, password]): return http.HttpResponseForbidden('缺少必传参数') if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username): return http.HttpResponseForbidden('请输入正确的用户名或手机号') if not re.match(r'^[0-9A-Za-z]{8,20}$', password): return http.HttpResponseForbidden('密码最少8位,最长20位') # 认证用户:使用账号查询用户是否存在,如果用户存在,再校验密码是否正确 user = authenticate(username=username, password=password) if user is None: return render(request, 'login.html', {'account_errmsg': '账号或密码错误'}) # 状态保持 login(request, user) # 使用remembered确定状态保持周期(实现记住登录) if remembered != 'on': # 没有记住登录:状态保持在浏览器会话结束后就销毁 request.session.set_expiry(0) # 单位是秒 else: # 记住登录:状态保持周期为两周:默认是两周 request.session.set_expiry(None) # 响应结果 # 先取出next next = request.GET.get('next') if next: # 重定向到next response = redirect(next) else: # 重定向到首页 response = redirect(reverse('contents:index')) # 为了实现在首页的右上角展示用户名信息,我们需要将用户名缓存到cookie中 # response.set_cookie('key', 'val', 'expiry') response.set_cookie('username', user.username, max_age=3600 * 24 * 15) # 用户登录成功,合并cookie购物车到redis购物车 # response = merge_carts_cookies_redis(request=request, user=user, response=response) # 响应结果:重定向到首页 return response
def get(self, request): """处理QQ登录回调的业务逻辑""" # 获取code code = request.GET.get('code') if not code: return http.HttpResponseForbidden('获取code失败') # 创建工具对象 oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI) try: # 使用code获取access_token,code是一次性的,获取完一次access_token之后就失效了 access_token = oauth.get_access_token(code) except Exception: logger.error('OAuth2.0认证失败,获取access_token失败') return http.HttpResponseServerError('OAuth2.0认证失败') try: # 使用access_token获取openid openid = oauth.get_open_id(access_token) except Exception: logger.error('OAuth2.0认证失败,获取open_id失败') return http.HttpResponseServerError('OAuth2.0认证失败') # 使用openid判断该QQ用户是否绑定过美多商城的用户 try: oauth_user = OAuthQQUser.objects.get(openid=openid) except OAuthQQUser.DoesNotExist: # openid未绑定美多商城用户 # access_token_openid = generate_access_token(openid) # context = {'access_token_openid': access_token_openid} request.session['openid'] = openid return render(request, 'oauth_callback.html') else: # openid已绑定美多商城用户:oauth_user.user表示从QQ登陆模型类对象中找到对应的用户模型类对象 # Django的ORM login(request, oauth_user.user) # 重定向到state:从哪来,QQ登录完之后回哪而去 next = request.GET.get('state') response = redirect(next) response = merge_carts_cookies_redis(request=request, user=oauth_user.user, response=response) # 将用户名写入到cookies中 response.set_cookie('username', oauth_user.user.username, max_age=3600 * 24 * 15) # 响应QQ登录结果 return response
def post(self, request): mobile = request.POST.get('mobile') password = request.POST.get('password') sms_code_client = request.POST.get('sms_code') access_token_openid = request.POST.get('access_token_openid') # 校验参数 # 判断参数是否齐全 if not all([mobile, password, sms_code_client]): return http.HttpResponseForbidden('缺少必传参数') # 判断手机号是否合法 if not re.match(r'^1[3-9]\d{9}$', mobile): return http.HttpResponseForbidden('请输入正确的手机号码') # 判断密码是否合格 if not re.match(r'^[0-9A-Za-z]{8,20}$', password): return http.HttpResponseForbidden('请输入8-20位的密码') # 判断短信验证码是否一致 redis_conn = get_redis_connection('verify_code') sms_code_server = redis_conn.get('sms_%s' % mobile) if sms_code_server is None: return render(request, 'oauth_callback.html', {'sms_code_errmsg': '无效的短信验证码'}) if sms_code_client != sms_code_server.decode(): return render(request, 'oauth_callback.html', {'sms_code_errmsg': '输入短信验证码有误'}) # 判断openid是否有效:错误提示放在sms_code_errmsg位置 openid = check_access_token(access_token_openid) if not openid: return render(request, 'oauth_callback.html', {'openid_errmsg': 'openid已失效'}) # 使用手机号查询对应的用户展示与否 try: user = User.objects.get(mobile=mobile) except User.DoesNotExist: # 如果手机号不存在新建用户 User.objects.create_user(username=mobile, password=password, mobile=mobile) else: # 如果手机号用户存在,需要校验密码 if not user.check_password(password): return render(request, 'oauth_callback.html', {'account_errmsg': '账号或者密码错误'}) # 将新建用户或已存在用户绑定到openid # oauth_qq_user = OAuthQQUser(user=user, openid=openid) # oauth_qq_user.save() try: oauth_qq_user = OAuthQQUser.objects.create(user=user, openid=openid) except Exception as e: logger.error(e) return render(request, 'oauth_callback.html', {'qq_login_errmsg': 'QQ登陆失败'}) # 状态保持,重定向 login(request, user) # 重定向到state next = request.GET.get('state') response = redirect(next) # 将用户名写入到cookies中 response.set_cookie('username', oauth_qq_user.user.username, max_age=3600 * 24 * 15) # 用户登陆成功,合并cookie购物车到redis购物车 response = merge_carts_cookies_redis(request=request, user=user, response=response) # 响应QQ登陆结果 return response
def get(self, request): """Oauth2.0认证""" # 提取code请求参数 code = request.GET.get('code') if not code: return http.HttpResponseForbidden('缺少code') # 创建工具对象 oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI) try: # 使用code向QQ服务器请求access_token access_token = oauth.get_access_token(code) except Exception: logger.error('向QQ服务器请求access_token失败') return http.HttpResponseServerError('OAuth2.0认证失败') try: # 使用access_token向QQ服务器请求openid openid = oauth.get_open_id(access_token) except Exception: logger.error('向QQ服务器请求openid失败') return http.HttpResponseServerError('OAuth2.0认证失败') try: oauth_user = OAuthQQUser.objects.get(openid=openid) except OAuthQQUser.DoesNotExist: # 如果openid没绑定美多商城用户 access_token_openid = generate_access_token(openid) context = {'access_token_openid': access_token_openid} return render(request, 'oauth_callback.html', context) else: # 如果openid已绑定美多商城用户 # 实现状态保持 qq_user = oauth_user.user login(request, qq_user) # 响应结果 next = request.GET.get('state') response = redirect(next) # 登录时用户名写入到cookie,有效期15天 response.set_cookie('username', qq_user.username, max_age=3600 * 24 * 15) # 若用户登录成功,合并cookie中的购物车 merge_carts_cookies_redis(request=request, user=qq_user, response=response) return response
def post(self, request): """实现用户登录逻辑""" # 接受参数 username = request.POST.get('username') password = request.POST.get('password') remembered = request.POST.get('remembered') # 校验参数 if not all([username, password]): return http.HttpResponseForbidden('缺少必传参数') # 判断用户名是否是5-20个字符重复 if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username): return HttpResponseForbidden("请输入5-20个字符的用户名") # 判断密码是否是8-20个字符 if not re.match(r'^[a-zA-Z0-9]{8,20}$', password): return HttpResponseForbidden("请输入8-20个字符的密码") # 认证用户 user = authenticate(username=username, password=password) if user is None: return render(request, 'login.html', {'acount_errmsg': '帐号或密码错误'}) # 状态保持 login(request, user) # 使用remenber确定状态保持周期(实现记住登录) if remembered != 'on': # 没有记住登录:状态保持在浏览器会话结束后就销毁,单位是秒 request.session.set_expiry(0) else: # 记录状态保持周期为两周:默认是两周 request.session.set_expiry(None) response = redirect(reverse('contents:index')) # 先取出next next = request.GET.get('next') if next: response = redirect(next) # 为了实现在首页的右上角展示用户名信息,我们需要将用户名缓存到cookie中 response.set_cookie('username', user.username, max_age=3600 * 24 * 15) # 若用户登录成功,合并cookie中的购物车 merge_carts_cookies_redis(request=request, user=user, response=response) # 响应结果 return response
def post(self, request): """用户登录逻辑""" # 1. 接收参数 username = request.POST.get('username') password = request.POST.get('password') remembered = request.POST.get('remembered') # 2.校验参数 if not all([username, password]): return http.HttpResponseForbidden('缺少必传参数') # 校验用户名密码是否符合要求 if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username): return http.HttpResponseForbidden('请输入正确的用户名') if not re.match(r'[0-9A-Za-z]{8,20}$', password): return http.HttpResponseForbidden('密码最少8位,最长20位') # 3. 认证用户: 使用账号查询用户名是否存在,如果用户名存在,再校验密码 user = authenticate(username=username, password=password) if user is None: return render(request, 'login.html', {'account_errmsg': '账号或密码错误'}) # 4. 状态保持 login(request, user) # 使用remembered确定状态保持周期(实现记住登录) if remembered != 'on': # 用户没有记录登录:关闭浏览器会话结束 request.session.set_expiry(0) else: # 记住了登录: 状态保持为两周:默认是两周 request.session.set_expiry(None) # 先取出next查询字符串 next = request.GET.get('next') # 判断 next是否存在 if next: # 重定向到next response = redirect(next) else: # 重定向到首页 response = redirect(reverse('contents:index')) # 用户名写入到cookie中,过期时间为两周 # response.set_cookie('key', 'val', 'expiry') response.set_cookie('username', user.username, max_age=3600 * 24 * 15) # 用户登录成功,合并cookie购物车到redis购物车 response = merge_carts_cookies_redis(request=request, user=user, response=response) # 5. 响应结果 return response
def post(self ,request ): """line登入用戶註冊""" #提取參數 username = request.POST.get('username') mobile = request.POST.get('mobile') allow = request.POST.get('allow') access_token = request.POST.get('access_token') user_messages_dict = check_access_token(access_token) #校驗參數 if not all([username ,mobile ,allow ,access_token ]): return HttpResponseForbidden('缺少必傳參數') if not re.match('^[a-zA-Z0-9_-]{5,20}$' ,username ): return HttpResponseForbidden('請輸入5~20個字符的用戶名稱') count = User.objects.filter(username=username).count() if count == 1: return HttpResponseForbidden('該用戶名稱已存在') if not re.match('^09\d{8}$' ,mobile ): return HttpResponseForbidden('您輸入的手機號碼格式不正確') if allow != 'on': return HttpResponseForbidden('請勾選同意RockeT使用合約') if not user_messages_dict: return HttpResponseForbidden('userid已失效') #實現主體業務邏輯:創建line登入用戶 name = user_messages_dict.get('name') photo_url = user_messages_dict.get('picture') userid = user_messages_dict.get('sub') state = user_messages_dict.get('state') try: #用戶不存在,創建新用戶 user = User.objects.create_user(username=username ,mobile=mobile ) #寫入用戶line登入資訊 OAuthLineUser.objects.create(user=user ,name=name ,photo_url=photo_url ,userid=userid ) except Exception as e: logger.error(e) return render(request ,'login.html' ,{'errmsg':'創建用戶失敗'}) #實現狀態保持 login(request ,user ) #重定向到指定頁面:state #構造響應數據 if state == '/': response = redirect(reverse('users:info')) else: response = redirect(state) #將用戶登入資訊寫入到cookies response.set_cookie('username' ,username ,constants.LOGIN_COOKIE_EXPIRES ) response.set_cookie('photo_url' ,photo_url ,constants.LOGIN_COOKIE_EXPIRES ) #用戶登錄成功後,同樣商品將cookies購物車數據覆蓋寫入redis response = merge_carts_cookies_redis(request, user, response) #返回響應 return response
def get(self ,request ): #提取參數 code = request.GET.get('code') error = request.GET.get('error') state = request.GET.get('state') #判斷用戶是否授權 if error: return redirect(reverse('users:login')) try: #請求line接口獲取id_token id_token = get_id_token(code) #判斷是否成功授權,若授權失敗,立即中止註冊 if not id_token: return redirect(reverse('contents:index')) #請求line接口驗證並解碼id_token picture ,userid ,user_messages_dict = get_profile_information(id_token ,state ) except Exception as e: logger.error(e) return HttpResponseServerError('OAuth2.0認證失敗') #判斷用戶是否存在 try: oauth_line_user = OAuthLineUser.objects.get(userid=userid) except Exception: #用戶未用line登入過 #簽名用戶數據 access_token = generate_access_token(user_messages_dict) #構造響應數據 contents = { 'access_token':access_token , 'picture':picture , } #返回用戶加密數據和line用戶註冊頁面 return render(request ,'line_register.html' ,contents ) else: #實現狀態保持:oauth_line_user.user代表從oauth_line_user中找出對應的用戶模型類對象 login(request ,oauth_line_user.user ) #重定向到指定頁面:state if state == '/': response = redirect(reverse('contents:index')) else: response = redirect(state) #將用戶登入資訊寫入到cookies response.set_cookie('username' ,oauth_line_user.user.username ,constants.LOGIN_COOKIE_EXPIRES ) response.set_cookie('photo_url' ,oauth_line_user.photo_url ,constants.LOGIN_COOKIE_EXPIRES ) #用戶登錄成功後,同樣商品將cookies購物車數據覆蓋寫入redis response = merge_carts_cookies_redis(request, oauth_line_user.user, response) #返回響應 return response
def get(self,request): """处理QQ登录回调的业务逻辑""" # 1.获取code参数 code = request.GET.get('code') # state = request.GET.get('state','/') if not code: return http.HttpResponseForbidden('获取code失败') # 2.创建工具对象 oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI) try: # 使用code获取access_token access_token = oauth.get_access_token(code) # 使用access_token获取openid openid = oauth.get_open_id(access_token) except Exception as e: logger.error(e) return http.HttpResponseServerError('OAuth2.0认证失败') # 3.使用openid判断该QQ用户是否绑定过美多商城的用户 try: oauth_user = OAuthQQUser.objects.get(openid=openid) except OAuthQQUser.DoesNotExist: # openid未绑定过美多商城用户 access_token_openid = generate_access_token(openid) context = {'access_token_openid': access_token_openid} # 将加密后的openid进行渲染返回 return render(request, 'oauth_callback.html',context) else: # openid绑定过美多商城用户:oauth_user.user表示从QQ登陆模型类对象中找到关联的用户模型类对象 login(request,oauth_user.user) # 重定向到state:从哪来,QQ登录完之后回哪而去 next = request.GET.get('state') response = redirect(next) # 将用户名写入到 cookie中, 有效期为15天 response.set_cookie('username', oauth_user.user.username, max_age=3600 * 24 * 15) # 用户登录成功,合并cookie购物车到redis购物车 response = merge_carts_cookies_redis(request=request, user=oauth_user.user, response=response) # 响应QQ登录结果 return response
def post(self, request): """接收登入資料""" #接收參數 username = request.POST.get('username') password = request.POST.get('password') remembered = request.POST.get('remembered') #認證用戶 res = LoginBackend.authenticate(self, request, username=username, password=password) if type(res) == User: user = res else: return res # 狀態保持 login(request, user) # 使用remembered來實現狀態保持週期(記住登入) if remembered != 'on': #狀態保持在瀏覽器會話結束後銷毀 request.session.set_expiry(0) else: # 狀態保持使用默認時限 request.session.set_expiry(None) #返回響應:重定向到next或首頁 #檢查是否有指定登入後跳轉頁面 next = request.GET.get('next') if next: response = redirect(next) else: response = redirect(reverse('contents:index')) #網頁右上角刷新登入狀態,將用戶登入資訊保存在cookie response.set_cookie('username', user.username, constants.LOGIN_COOKIE_EXPIRES) #用戶登錄成功後,同樣商品將cookies購物車數據覆蓋寫入redis response = merge_carts_cookies_redis(request, user, response) #返回響應 return response
def get(self, request): '''处理QQ回调的业务逻辑''' # 获取code code = request.GET.get('code') if code is None: return http.HttpResponseServerError('获取code失败') # 创建工具对象 oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI) try: # 使用code获取access_token access_token = oauth.get_access_token(code) # 使用access_token获取openid openid = oauth.get_open_id(access_token) # print(openid) except Exception as e: logger.error(e) return http.HttpResponseServerError('OAuth2.0认证失败') # 使用openid判断该QQ用户是否绑定过美多商城的用户 try: oauth_user = OAuthQQUser.objects.get(openid=openid) # print(oauth_user) except OAuthQQUser.DoesNotExist: # openid未绑定美多商城用户 access_token_openid = generate_access_token(openid) context = {'access_token_openid': access_token_openid} return render(request, 'oauth_callback.html', context) else: # openid已绑定美多商城用户:oauth_user.user表示从QQ登陆模型类对象中找到用户模型类对象 login(request, oauth_user.user) # 重定向到state next = request.GET.get('state') response = redirect(next) # 将用户名写入到cookies中 response.set_cookie('username', oauth_user.user.username, max_age=3600 * 24 * 15) # 用户登陆成功,合并cookie购物车到redis购物车 response = merge_carts_cookies_redis(request=request, user=oauth_user.user, response=response) # 响应QQ登陆结果 return response
def post(self, request): """实现绑定用户的逻辑""" # 1. 接收参数 mobile = request.POST.get('mobile') password = request.POST.get('password') sms_code_client = request.POST.get('sms_code') access_token_openid = request.POST.get('access_token_openid') # 接收重定向地址 # state = request.GET.get('state', '/') # 2. 校验参数 # 判断参数是否齐全 if not all([mobile, password, sms_code_client]): return http.HttpResponseForbidden('缺少必传参数') # 判断手机号是否合法 if not re.match(r'^1[3-9]\d{9}$', mobile): return http.HttpResponseForbidden('请输入正确的手机号码') # 判断密码是否合格 if not re.match(r'^[0-9A-Za-z]{8,20}$', password): return http.HttpResponseForbidden('请输入8-20位的密码') # 判断短信验证码是否一致 redis_conn = get_redis_connection('verify_code') sms_code_server = redis_conn.get('sms_%s' % mobile) if sms_code_server is None: return render(request, 'oauth_callback.html', {'sms_code_errmsg': '无效的短信验证码'}) if sms_code_client != sms_code_server.decode(): return render(request, 'oauth_callback.html', {'sms_code_errmsg': '输入短信验证码有误'}) # 3. 判断openid是否有效:openid使用itsdangerous签名之后只有600秒的有效期 openid = check_access_token(access_token_openid) if not openid: return render(request, 'oauth_callback.html', {'openid_errmsg': 'openid已失效'}) # 4. 保存注册数据 try: # 4.1 使用手机号查询对应的用户是否存在 user = User.objects.get(mobile=mobile) except User.DoesNotExist: # 4.2 如果手机号用户不存在,使用手机号作为用户名,新建用户 user = User.objects.create_user(username=mobile, password=password,mobile=mobile) else: # 4.3 用户存在, 校验密码 if not user.check_password(password): return render(request, 'oauth_callback.html', {'account': '账号或密码错误'}) # 5. 将新建用户和已存在用户和 openid绑定到一起 # create封装了创建模型类对象和保存对象方法 try: oauth_qq_user = OAuthQQUser.objects.create(user=user, openid=openid) except Exception as e: logger.error(e) # 输出错误信息到日志中 return render(request, 'oauth_callback.html', {'qq_login_errmsg': '账号或密码错误'}) # 6. 实现状态保持 login(request, oauth_qq_user.user) # 7.响应绑定结果 next = request.GET.get('state') # 从查询字符串中取出state所在地址 # 重定向state, state从哪来,QQ登录完之后回哪而去 response = redirect(next) # 登录时用户名写入到cookie,有效期15天 response.set_cookie('username', oauth_qq_user.user.username, max_age=3600 * 24 * 15) # 用户登录成功,合并cookie购物车到redis购物车 response = merge_carts_cookies_redis(request=request, user=user, response=response) return response
def post(self, request): """ 实现用户注册逻辑 :param request: 请求对象 :return: 注册结果 """ # 接受参数 username = request.POST.get('username') password = request.POST.get('password') password2 = request.POST.get('password2') mobile = request.POST.get('mobile') sms_code_client = request.POST.get('sms_code') allow = request.POST.get('allow') # 校验参数:前后端的校验需要分开,避免恶意用户越过前端发请求, # 要保证后端的安全,前后端的校验逻辑相同 # 判断参数是否齐全 # all(列表)回去校验列表中的元素是否为空,只要有一个为空,返回false if not all( [username, password, password2, mobile, sms_code_client, allow]): return HttpResponseForbidden("缺少必传参数") # 判断用户名是否是5-20个字符重复 if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username): return HttpResponseForbidden("请输入5-20个字符的用户名") # 判断密码是否是8-20个字符 if not re.match(r'^[a-zA-Z0-9]{8,20}$', password): return HttpResponseForbidden("请输入8-20个字符的密码") # 判断两次输入的密码是否一致 if password != password2: return HttpResponseForbidden("再次输入的密码不一致") # 判断手机号码是否合法 if not re.match(r'^1[3-9]\d{9}$', mobile): return HttpResponseForbidden("请输入正确的手机号码") # 判断短信验证码是否输入正确 try: redis_conn = get_redis_connection('verify_code') sms_code_server = redis_conn.get('sms_%s' % mobile) except Exception as e: logger.error(e) if sms_code_server is None: return render(request, 'register.html', {'register_errmsg': '短信验证码已经失效'}) if sms_code_server.decode() != sms_code_client: return render(request, 'register.html', {'register_errmsg': '短信验证码输入有误'}) # 判断用户是否勾选了协议 if allow != "on": return HttpResponseForbidden("请勾选用户协议") # 保存注册数据,是注册业务的核心 try: # create_user() 创建用户密码加密 user = User.objects.create_user(username=username, password=password, mobile=mobile) except DatabaseError as e: logger.error(e) return render(request, 'register.html', {'register_errmsg': '注册失败'}) # 状态保持 login(request, user) # 响应结果:重定向到首页 # 为了实现在首页的右上角展示用户名信息,我们需要将用户名缓存到cookie中 response = redirect(reverse('contents:index')) response.set_cookie('username', user.username, max_age=3600 * 24 * 15) # 若用户登录成功,合并cookie中的购物车 merge_carts_cookies_redis(request=request, user=user, response=response) # 响应结果 return response
def post(self, request): """实现绑定用户的逻辑""" # 接收参数 mobile = request.POST.get('mobile') password = request.POST.get('password') sms_code_client = request.POST.get('sms_code') access_token_openid = request.POST.get('access_token_openid') # 校验参数 # 判断参数是否齐全 if not all([mobile, password, sms_code_client]): return http.HttpResponseForbidden('缺少必传参数') # 判断手机号是否合法 if not re.match(r'^1[3-9]\d{9}$', mobile): return http.HttpResponseForbidden('请输入正确的手机号码') # 判断密码是否合格 if not re.match(r'^[0-9A-Za-z]{8,20}$', password): return http.HttpResponseForbidden('请输入8-20位的密码') # 判断短信验证码是否一致 redis_conn = get_redis_connection('verify_code') sms_code_server = redis_conn.get('sms_%s' % mobile) if sms_code_server is None: return render(request, 'oauth_callback.html', {'sms_code_errmsg': '无效的短信验证码'}) if sms_code_client != sms_code_server.decode(): return render(request, 'oauth_callback.html', {'sms_code_errmsg': '输入短信验证码有误'}) # 判断openid是否有效:openid使用itsdangerous签名之后只有600秒的有效期 openid = request.session['openid'] # cookie key value # 用户1 sessionid fb09lgmhb3jiso0e9c1457xtpogmjph7 # 用户2 sessionid fb09lgmhb3jiso0e9c1457xtpogmjph8 # session # 用户1 fb09lgmhb3jiso0e9c1457xtpogmjph7 {'openid': '用户1的openid'} # 用户2 fb09lgmhb3jiso0e9c1457xtpogmjph8 {'openid': '用户2的openid'} # openid = check_access_token(access_token_openid) # if not openid: # logger.error('用户openid过期或签名错误') # return render(request, 'oauth_callback.html', {'openid_errmsg': '绑定失败,请重新绑定'}) # 使用手机号查询对应的用户是否存在 try: user = User.objects.get(mobile=mobile) except User.DoesNotExist: # 如果手机号用户不存在,新建用户 user = User.objects.create_user(username=mobile, password=password, mobile=mobile) else: # 如果手机号用户存在,需要校验密码 if not user.check_password(password): return render(request, 'oauth_callback.html', {'account_errmsg': '账号或密码错误'}) # 将新建用户、已存在用户绑定到openid # oauth_qq_user = OAuthQQUser(user=user, openid=openid) # oauth_qq_user.save() try: oauth_qq_user = OAuthQQUser.objects.create(user=user, openid=openid) except Exception as e: logger.error(e) return render(request, 'oauth_callback.html', {'qq_login_errmsg': '账号或密码错误'}) # openid已绑定美多商城用户:oauth_user.user表示从QQ登陆模型类对象中找到对应的用户模型类对象 login(request, oauth_qq_user.user) # 重定向到state:从哪来,QQ登录完之后回哪而去 next = request.GET.get('state') response = redirect(next) response = merge_carts_cookies_redis(request=request, user=user, response=response) # 将用户名写入到cookies中 response.set_cookie('username', oauth_qq_user.user.username, max_age=3600 * 24 * 15) # 响应QQ登录结果 return response