Exemple #1
0
    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
Exemple #2
0
    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)
Exemple #3
0
    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
Exemple #4
0
    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
Exemple #5
0
    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
Exemple #6
0
    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
Exemple #7
0
 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
Exemple #8
0
    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
Exemple #9
0
    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
Exemple #10
0
    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
Exemple #11
0
    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
Exemple #12
0
    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
Exemple #13
0
 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
Exemple #14
0
    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
Exemple #15
0
    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
Exemple #16
0
    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