Exemple #1
0
    def get(self, request):  # oauth认证
        code = request.GET.get("code")
        url = "https://api.weibo.com/oauth2/access_token"
        cn = OAuthWB(client_id=settings.APP_KEY,
                     client_key=settings.APP_SECRET,
                     redirect_uri=settings.WEIBO_REDIRECT_URI)
        # requests认证oauth
        dict = cn.get_access_token(code)

        uid = dict.get("uid")
        print(type(uid))
        if uid is None:
            return HttpResponse("认证失败")

        try:  # 得不到报错try 一下
            # 匹配一个微博用户对象

            weibo_model = OAuthSINAUser.objects.get(openid=uid)
            print(type(weibo_model))
        except:
            uid = generate_openid_signature(uid)
            return render(request, 'oauth_callback.html', {"openid": uid})

        user = weibo_model.user

        login(request, user)

        response = redirect(request.GET.get('state', '/'))

        response.set_cookie('username', user.username, 60 * 60 * 24 * 14)
        merge_cart_cookie_to_redis(request, response)
        return response
Exemple #2
0
    def post(self, request):
        # 获取表单账号,密码
        username = request.POST.get('username')
        password = request.POST.get('password')
        remembered = request.POST.get('remembered')
        # 校验
        # 根据表单提交用户名获取数据库中本条user信息,基本逻辑代码
        # user = User.objects.get(username= username)
        # user.check_password(password)

        # 实现手机号或其他多账号登录
        # 通过自定义用户认证后端实现
        # django中auth自带认证方法
        user = authenticate(username=username, password=password)
        if user is None:
            return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'})
        # 根据是否勾选记住密码保持状态
        login(request, user)
        if remembered != 'on':
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(None)

        # 在首页显示用户名
        response = redirect(request.GET.get('next', '/'))  # 创建好响应对象
        response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE if remembered == 'on' else None)


        # 登录成功那一刻合并购物车
        merge_cart_cookie_to_redis(request, user, response)
        # 响应结果重定向到首页
        return response
Exemple #3
0
    def post(self, request, *args, **kwargs):
        """
        1.提取前端传来的参数
        2.获取序列化器对象,传入需要反序列化的参数
        3.开启校验
        4.保存校验结果,返回的是保存好的user对象
        5.生成jwt令牌
        6.构造响应对象并返回
        """
        serializer = QQAuthUserSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()

        # 5.生成jwt令牌

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        response = Response({
            'token': token,
            'username': user.username,
            'user_id': user.id
        })
        # 做cookie购物车合并到redis操作
        merge_cart_cookie_to_redis(request, user, response)

        return response
Exemple #4
0
    def post(self, request):
        '''openid绑定用户接口'''

        # 1.创建序列化器进行反序列化
        serializer = QQAuthUserSerializer(data=request.data)

        # 2.调用is_valid()进行校验
        serializer.is_valid(raise_exception=True)

        # 3.调用序列化器的save方法
        user = serializer.save(
        )  # 因为序列化器传入data,说明调用了create()方法,create()方法返回的是个user对象

        # 4.生成JWT状态保存 token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER  # 引用jwt中的叫jwt_payload_handler函数(生成payload)
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER  # 函数引用,生成jwt

        payload = jwt_payload_handler(user)  # 根据user生成用户相关的载荷
        token = jwt_encode_handler(payload)  # 传入载荷生成完整的jwt

        # 响应对象
        response = Response({
            'token': token,
            'username': user.username,
            'user_id': user.user_id
        })

        # 调用合并购物车函数
        # response是个对象,对象是一个可变类型,对它进行改变,它原本就发生了变化,不需要再进行返回
        merge_cart_cookie_to_redis(request, user, response)

        # 5.响应
        return response
Exemple #5
0
    def post(self, request):
        """openid绑定用户"""
        # 1. 接收表单中的数据
        query_dict = request.POST
        # dict1 = query_dict.dict()
        # dict1.values()
        mobile = query_dict.get('mobile')
        password = query_dict.get('password')
        sms_code = query_dict.get('sms_code')
        openid = query_dict.get('openid')
        # 2. 校验
        if all([mobile, password, sms_code, openid]) is False:
            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_codes')
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        redis_conn.delete('sms_%s' % mobile)
        if sms_code_server is None:
            return http.HttpResponseForbidden('短信验证码已过期')
        if sms_code != sms_code_server.decode():
            return http.HttpResponseForbidden('短信验证码填写错误')
        try:
            # 3. 查询手机号是否已注册过
            user = User.objects.get(mobile=mobile)
            # 4. 注册过再校验传入的密码是否正确
            if user.check_password(password) is False:
                return http.HttpResponseForbidden('绑定失败')
        except User.DoesNotExist:
            # 5. 如果手机号是新的,就创建一个新用户
            user = User.objects.create_user(username=mobile,
                                            password=password,
                                            mobile=mobile)
        # 对openid进行解密
        openid = check_open_id(openid)
        if openid is None:
            return http.HttpResponseForbidden('openid无效')  # 可以自己制作一个页面专门处理该事件
        # 6.openid绑定美多新老用户
        OAuthQQUser.objects.create(
            openid=openid,
            user=user,
        )
        # 7. 状态保持
        login(request, user)

        # 8. 存储cookie中的username
        response = redirect(request.GET.get('state') or '/')
        response.set_cookie('username',
                            user.username,
                            max_age=settings.SESSION_COOKIE_AGE)

        # 合并购物车
        merge_cart_cookie_to_redis(request, response)

        # 9. 重定向到来源
        return response
Exemple #6
0
    def post(self, request):
        """账号密码登录实现逻辑"""

        # 接收用户名
        username = request.POST.get('username')
        password = request.POST.get('password')
        remembered = request.POST.get('remembered')
        if all([username, password]) is False:
            return http.HttpResponseForbidden('缺少必传参数')
        # 校验
        # user = User.objects.get(username=username)
        # user.check_password(password)
        # 登录认证
        user = authenticate(username=username, password=password)
        if user is None:
            return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'})

        #设置状态保持的周期
        if remembered != 'on':  # 没有勾选记住登录
            request.session.set_expiry(0)

        # 状态保持!
        login(request, user)

        response = redirect(request.GET.get('next') or '/' )#创建响应对象
        response.set_cookie('username',user.username,max_age=60*60)
        # 登陆成功那一刻合并购物车
        merge_cart_cookie_to_redis(request, user, response)
        # 响应结果重定向到首页
        return response
Exemple #7
0
    def post(self, request):
        # 接受请求数据
        query_dic = request.POST
        username = query_dic.get('username')
        password = query_dic.get('password')
        remembered = query_dic.get('remembered')
        # 校验
        if all([username, password]) is False:
            return http.HttpResponseForbidden('缺少必传参数')

        # 用户登录验证
        user = authenticate(request, username=username, password=password)
        if user is None:
            return render(request, 'login.html',
                          {'account_errmsg': '用户名或密码错误'})
        # 状态保持
        login(request, user)
        if remembered != 'on':
            request.session.set_expiry(0)
        # 获取登录来源
        next = request.GET.get('next')
        # 重定向到首页
        response = redirect(next or '/')
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
        merge_cart_cookie_to_redis(request, response)
        return response
Exemple #8
0
    def post(self, request):
        """登录功能逻辑"""
        # 1.接收请求体表单数据
        query_dict = request.POST
        username = query_dict.get('username')
        password = query_dict.get('password')
        remembered = query_dict.get('remembered')

        # 2.校验
        user = authenticate(request, username=username, password=password)
        # 如果登录失败
        if user is None:
            return render(request, 'login.html',
                          {'account_errmsg': '用户名或密码错误'})
        # 3.状态保持
        login(request, user)

        # 如果用户没有勾选记住登录
        # 如果session过期时间设置为None,表示使用默认的14天,如果设置为0,代表关闭浏览器失效
        # 如果cookie过期时间设置为None,表示关闭浏览器就过期,如果设置为0,代表直接删除
        if remembered is None:
            request.session.set_expiry(0)  # 是指session的过期时间为关闭浏览器过期
        # 4.重定向

        next = request.GET.get(
            'next')  # 尝试去获取查询参数中是否有用户界面的来源,如果有来源,成功登录后跳转到来源界面
        response = redirect(next or '/')  # 创建响应对象
        # 给cookie设置username
        response.set_cookie('username',
                            user.username,
                            max_age=None if remembered is None else
                            settings.SESSION_COOKIE_AGE)
        # 合并购物车
        merge_cart_cookie_to_redis(request, response)
        return response
Exemple #9
0
    def post(self, request):

        username = request.POST.get('username')
        password = request.POST.get('password')
        remembered = request.POST.get('remembered')
        # 多账号登录简化版
        # if re.match(r'^1[3-9]\d{9}$', username):
        #     User.USERNAME_FIELD = 'mobile'

        user = authenticate(request, username=username, password=password)
        # User.USERNAME_FIELD = 'username'

        if user is None:
            return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'})

        login(request, user)

        if remembered != 'on':
            request.session.set_expiry(0)

        next = request.GET.get('next')
        response = redirect(next or '/')
        response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE if remembered else None)
        # 在此就做合并购物车
        merge_cart_cookie_to_redis(request, response)
        return response
Exemple #10
0
    def post(self, request):

        # 1. 创建序列化器,表单形式--requesnt.data
        s = QQUserSerializer(data=request.data)

        # 2. 校验请求参数是否合法: serializer.is_valid()
        s.is_valid(raise_exception=True)

        # 3. 绑定openid与美多用户:  serializer.save()   -> serializer.create()
        #创建绑定的梅朵用户对象并且返回
        user = s.save()  # 返回绑定的美多用户对象

        # 4. 生成并响应 jwt, user_id, username,完成QQ登录
        # 生成jwt
        from rest_framework_jwt.settings import api_settings
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER  # 生payload部分的方法(函数)
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER  # 生成jwt的方法(函数)

        payload = jwt_payload_handler(user)  # 生成payload, 得到字典
        token = jwt_encode_handler(payload)  # 生成jwt字符串

        # 响应数据
        context = {
            'token': token,
            'user_id': user.id,
            'username': user.username
        }

        response = Response(context)
        # 合并购物车商品
        merge_cart_cookie_to_redis(request, response, user)
        return Response(context)
Exemple #11
0
    def post(self, request):
        # 1.接收表单数据mobile,password,sms_code,openid
        query_dict = request.POST
        mobile = query_dict.get('mobile')
        password = query_dict.get('password')
        sms_code = query_dict.get('sms_code')
        openid = query_dict.get('openid')


        # 2.校验
        if all([mobile, password, sms_code, openid]) is False:
            return http.HttpResponseForbidden('缺少必传参数')

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入正确的手机号')

        if not re.match('^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('请输入8-20位的密码')

        # 对openid进行解密,将原始openid存储到表中
        openid = generate_origin_openid(openid)
        if openid is None:
            return http.HttpResponseForbidden('openid无效')

        # 获取redis中的短信验证码
        redis_conn = get_redis_connection('verify_codes')
        sms_code_server_bytes = redis_conn.get('sms_code_%s' % mobile)
        # 让短信验证码成为一次性的
        redis_conn.delete('sms_code_%s' % mobile)
        # 判断短信验证码是否过期
        if sms_code_server_bytes is None:
            return http.HttpResponseForbidden('短信验证码已过期')
        # 转换reids中短信验证码类型
        sms_code_server = sms_code_server_bytes.decode()
        # 判断用户验证码是否正确
        if sms_code != sms_code_server:
            return http.HttpResponseForbidden('验证码输入有误')

        # 以mobile字典查询user表,如果查询到就认为ie是老用户,直接用openid和老用户绑定
        try:
            user = User.objects.get(mobile=mobile)
            if user.check_password(password) is False:
                return http.HttpResponseForbidden('老用户密码错误')
        except User.DoesNotExist:
            # 如果是美多新用户,就创建一个新用户和openid绑定
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)


        # 3.openid绑定user
        OAuthQQUser.objects.create(openid=openid, user=user)

        # 状态保持
        login(request, user)
        response = redirect(request.GET.get('state'))
        # 向cookie中存储username
        response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE)

        # 合并购物车数据
        merge_cart_cookie_to_redis(request,response)
        return response
Exemple #12
0
    def post(self, request):
        # 接收请体的表单数据 POST
        query_dict = request.POST
        mobile = query_dict.get('mobile')
        password = query_dict.get('password')
        sms_code_client = query_dict.get('sms_code')
        openid = query_dict.get('openid')
        # 校验
        if all([mobile, password, sms_code_client, openid]) is False:
            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连接对象
        redis_conn = get_redis_connection('verify_code')
        # 获取短信验证码
        sms_code_server = redis_conn.get('sms_code_%s' % mobile)
        # 让短信验证码只能用一次
        redis_conn.delete('sms_code_%s' % mobile)
        # 判断是否过期
        if sms_code_server is None:
            return http.HttpResponseForbidden('短信验证码过期')
        # 判断用户短信验证码是否输入正确
        if sms_code_client != sms_code_server.decode():
            return http.HttpResponseForbidden('短信验证码输入错误')

        try:
            # 利用手机号查询user表,如果查询到用户,说明是老用户
            user = User.objects.get(mobile=mobile)
            # 如果是老用户,再校验一个密码是否能对上
            if user.check_password(password) is False:
                return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})
        except User.DoesNotExist:
            # 如果使用手机号查询不到user,说明是新用户
            # 新用户就create_user 方法创建用户
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)


        # 对openid进行解密
        openid = check_openid_signature(openid)
        if openid is None:
            return http.HttpResponseForbidden('openid无效')

        # 新老用户绑定openid
        OAuthQQUser.objects.create(
            user=user,
            # user_id=user.id,
            openid=openid,
        )
        # 登录成功后要做的事情
        login(request, user)
        response = redirect(request.GET.get('state') or '/')
        response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE)
        # 合并
        merge_cart_cookie_to_redis(request, response)
        return response
Exemple #13
0
    def post(self, request):
        """
        实现登录逻辑
        :param request:
        :return: 登录结果
        """
        username = request.POST.get('username')
        password = request.POST.get('password')
        remembered = request.POST.get('remembered')

        # django自带认证登录用户
        user = authenticate(request, username=username, password=password)
        if user is None:
            return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'})

        # 实现状态保持
        login(request, user)
        # 设置状态保持时长
        if remembered is None:
            # 如果没有勾选记住登录,session会话在浏览器关闭就结束
            # 默认为两周,设置为None表示默认
            request.session.set_expiry(0)

        next = request.GET.get('next', '/')
        response = redirect(next)  # 登录成功重定向到next页或首页

        # 登录成功合并购物车数据
        merge_cart_cookie_to_redis(request, response)
        # 用户名写入到cookie,有效期两周(前端获取到用于展示用户信息)
        # None表示在浏览器关闭就清除,0表示刚生成就清除了
        response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE if remembered else None)

        return response
    def post(self, request):
        # 接收前端传入的表单数据
        query_dict = request.POST
        username = query_dict.get('username')
        password = query_dict.get('pwd')
        remembered = query_dict.get('remembered')

        # 校验
        # authenticate 用户认证
        user = authenticate(request, username=username, password=password)

        # 判断用户是否通过认证
        if user is None:
            return render(request, 'login.html',
                          {'account_errmsg': '用户名或密码错误'})
        # 状态保持
        login(request, user)
        # # 如果用户没有记住登录
        if remembered != 'on':
            request.session.set_expiry(0)  # 把session的过期时间设置为0 表示会话结束后就过期
        # /login/?next=/info/
        # /login/
        # 用户如果有来源就重定向到来源,反之就去首页
        response = redirect(request.GET.get('next')
                            or '/')  # 创建重定向响应对象   SESSION_COOKIE_AGE
        # response.set_cookie('username', user.username, max_age=(60 * 60 * 24 * 7 * 2) if remembered else None)
        response.set_cookie(
            'username',
            user.username,
            max_age=settings.SESSION_COOKIE_AGE if remembered else None)
        # print(settings.SESSION_COOKIE_AGE)
        # 重定向到指定页
        # return http.HttpResponse('登录成功,来到首页')
        merge_cart_cookie_to_redis(request, response)
        return response
    def get(self, request):

        code = request.GET.get('code')
        if code is None:
            return http.HttpResponseForbidden('缺少code')
        client = APIClient(app_key=settings.SINA_CLIENT_ID,
                           app_secret=settings.SINA_CLIENT_SECRET,
                           redirect_uri=settings.SINA_REDIRECT_URI)

        try:
            token_dict = client.request_access_token(code)
            access_token = token_dict.access_token
        except Exception as e:
            logger.error(e)
            return http.HttpResponseForbidden('code无效')

        try:
            sina_u = OAuthSinaUser.objects.get(uid=access_token)
        except OAuthSinaUser.DoesNotExist:
            return http.JsonResponse({'access_token': access_token})
        else:
            user = sina_u.user
            data = {
                'user_id': user.id,
                'username': user.username,
                'token': access_token
            }
            login(request, user)
            response = http.JsonResponse(data)
            response.set_cookie('username',
                                user.username,
                                max_age=settings.SESSION_COOKIE_AGE)
            merge_cart_cookie_to_redis(request, response)
            return response
Exemple #16
0
    def post(self, request):
        """openid绑定到用户"""

        # 创建序列化器对象,进行反序列化

        serializer = QQAuthUserSerializer(data=request.data)

        # 开启校验
        serializer.is_valid(raise_exception=True)
        # 保存校验结果,并接收
        user = serializer.save()

        # 手动生成jwt Token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER  # 加载生成载荷函数
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER  # 加载生成token函数
        # 获取user对象

        payload = jwt_payload_handler(user)  # 生成载荷
        token = jwt_encode_handler(payload)  # 根据载荷生成token

        response = Response({
            'token': token,
            'username': user.username,
            'user_id': user.id
        })

        # 做cookie购物车合并到redis操作
        merge_cart_cookie_to_redis(request, user, response)

        return response
Exemple #17
0
 def post(self,request):
     mobile = request.POST.get('mobile')
     pwd = request.POST.get('password')
     sms_code_client = request.POST.get('sms_code')
     openid = request.POST.get('openid')
     if not all([mobile,pwd,sms_code_client,openid]):
         return HttpResponseForbidden('缺少必传参数')
     if not re.match(r'^1[3-9]\d{9}',mobile):
         return HttpResponseForbidden('电话号码错误')
     redis_conn=get_redis_connection('verify_code')
     ver_code=redis_conn.get('sms_%s' % mobile)
     # if ver_code is None:
     #     return JsonResponse({'code': RETCODE.SMSCODERR, 'errmsg': '短信验证码已过期'})
     # if ver_code.decode()!=sms_code_client:
     #     return JsonResponse({'code': RETCODE.SMSCODERR, 'errmsg': '短信验证码错误'})
     if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd):
         return HttpResponseForbidden('请输入8-20位的密码')
     openid=check_openid_signature(openid)
     if not openid:
         return HttpResponseForbidden('绑定失败')
     try:
         user=User.objects.get(mobile=mobile)
         if not user.check_password(pwd):
             return JsonResponse({'code': RETCODE.PWDERR, 'errmsg': '密码错误'})
     except User.DoesNotExist:
         user=User.objects.create_user(username=mobile,password=pwd,mobile=mobile)
     OAuthQQUser.objects.create(user=user, openid=openid)
     login(request, user)
     response = redirect(request.GET.get('state') or '/')
     response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE)
     merge_cart_cookie_to_redis(request=request, response=response)
     return response
Exemple #18
0
    def post(self, request):
        """实现openid绑定用户逻辑"""
        # 接收数据
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        sms_code = request.POST.get('sms_code')
        openid = request.POST.get('openid')

        if all([mobile, password, sms_code, openid]) is False:
            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_coon = get_redis_connection('verify_code')
        sms_code_server = redis_coon.get('sms_%s' % mobile)  # 获取redis中的短信验证码

        if sms_code_server is None or sms_code != sms_code_server.decode():
            return http.HttpResponseForbidden('短信验证码有误')

        # 校验openid
        openid = check_openid_sign(openid)
        if openid is None:
            return http.HttpResponseForbidden('openid无效')

        # 绑定用户
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            # 当前要绑定的用户是一个新用户
            user = User.objects.create_user(
                username=mobile,
                password=password,
                mobile=mobile,
            )
        else:
            # 当前要绑定的用户是已存在
            if user.check_password(password) is False:
                return http.HttpResponseForbidden('账号或密码错误')

        # 如果代码能执行到这里,用户user绝对已经有了
        # 用户openid和user绑定
        OAuthQQUser.objects.create(user=user, openid=openid)

        # 重定向
        login(request, user)

        response = redirect(request.GET.get('state'))
        response.set_cookie('username',
                            user.username,
                            max_age=settings.SESSION_COOKIE_AGE)
        # 登陆成功那一刻合并购物车
        merge_cart_cookie_to_redis(request, user, response)
        return response
Exemple #19
0
    def post(self, request):
        """
        实现登录逻辑
        :param request: 请求对象
        :return:  登录结果
        """

        # 接收参数

        username = request.POST.get('username')

        password = request.POST.get('password')

        remembered = request.POST.get('remembered')

        # 认证登录用户

        user = authenticate(username=username, password=password)

        if user is None:
            return render(request, 'login.html',
                          {'account_errmsg': '用户名或密码错误'})

        # 实现登录状态保持

        login(request, user)

        # 设置状态保持的周期

        if remembered != 'on':
            # 没有记住用户: 浏览器会话结束就过期,默认是两周

            request.session.set_expiry(0)

        next = request.GET.get('next')

        # if next:
        #
        #     response = redirect(next)
        #
        #
        # else:
        #     # 响应登录结果
        #
        #     # return redirect(reverse('contents:index'))  实现首页显示登录名,此处要将用户名等信息写出cookie
        #
        #     response = redirect(reverse('contents:index'))

        response = redirect(next or "/")

        # 登录时用户名写入cookie,有效期14天
        response.set_cookie('username',
                            user.username,
                            max_age=(None if remembered is None else
                                     settings.SESSION_COOKIE_AGE))

        merge_cart_cookie_to_redis(request, response)

        return response
Exemple #20
0
    def post(self, request, *args, **kwargs):
        response = super().post(request, *args, **kwargs)

        # 合并购物车
        user = self.user
        merge_cart_cookie_to_redis(request, user, response)

        return response
Exemple #21
0
    def get(self, request):
        # 1.获取前端传入的code
        code = request.query_params.get('code')
        if not code:
            return Response({'message': '缺少code'},
                            status=status.HTTP_400_BAD_REQUEST)

        # 2.创建QQ登录工具对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)  # 不需要next参数

        try:
            # 3.调用它里面get_access_token(code) 用code响应QQ服务器获取access_token
            access_token = oauth.get_access_token(code)

            # 4.调用它里面get_open_id(access_token) 用access_token响应QQ服务器获取openid
            openid = oauth.get_open_id(access_token)
        except Exception as e:  # 捕获其他异常
            logging.info(e)  # 输出到终端和日志文件中
            return Response({'message': 'QQ服务器不可用'},
                            status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 5.查询数据库有没有这个openid
        try:
            authQQUserModel = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:

            # 6.如果没有这个openid,没有绑定用户,把openid加密之后响应给前端,让前端先暂存一会,等待绑定时使用
            # access_token是由于前端写错了,本应该是openid
            # 没有绑定openid,无法识别用户,不能使用服务器资源,所以只能将openid传给前端,让前端保存
            # 因为openid是QQ用户的唯一身份标志,直接传前端可见,需要进行加密传输
            access_token_openid = generate_save_user_token(openid)
            return Response({'access_token': access_token_openid})

        else:
            # 7.如果有这个openid,直接代码登录成功,给前端返回JWT状态保存信息
            # 获取到openid 关联的user
            user = authQQUserModel.user  # 通过外键获取user模型对象

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER  # 引用jwt中的叫jwt_payload_handler函数(生成payload)
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER  # 函数引用,生成jwt

            payload = jwt_payload_handler(user)  # 根据user生成用户相关的载荷
            token = jwt_encode_handler(payload)  # 传入载荷生成完整的jwt

            # 响应对象
            response = Response({
                'token': token,
                'username': user.username,
                'user_id': user.user_id
            })

            # 调用合并购物车函数
            # response是个对象,对象是一个可变类型,对它进行改变,它原本就发生了变化,不需要再进行返回
            merge_cart_cookie_to_redis(request, user, response)

            return response
Exemple #22
0
    def post(self, request):
        """绑定用户处理"""
        # 1.接受数据
        query_dict = request.POST
        mobile = query_dict.get('mobile')
        password = query_dict.get('password')
        sms_code = query_dict.get('sms_code')
        openid = query_dict.get('openid')
        # 2.校验
        if all([mobile, password, sms_code, openid]) is False:
            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数据库获取短信标识
        redis_conn = get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms_code_%s' % mobile)
        if sms_code_server is None:
            return render(request, 'oauth_callback.html',
                          {'sms_code_errmsg': '短信验证码已失效'})
        if sms_code_server.decode() != sms_code:
            return render(request, 'oauth_callback.html',
                          {'sms_code_errmsg': '请输入正确的验证码'})
        # 对openid进行解密
        openid = check_openid_signature(openid)
        if openid is None:
            return http.HttpResponseForbidden('openid无效')

        # 3.处理逻辑
        # 先判断用户是否存在,如果用户的手机号在user表中查不到创建一个新的用户
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            # 表示没有该用户,需要创建一个新的用户
            user = User.objects.create_user(mobile=mobile,
                                            password=password,
                                            username=mobile)

        else:
            # 用户存在,判断该用户的密码是否正确
            if user.check_password(password) is False:
                return render(request, 'oauth_callback.html',
                              {'account_errmsg': '用户名或者密码错误'})
            # openid和用户绑定
            OAuthQQUser.objects.create(openid=openid, user=user)

            login(request, user)  # 保持状态
            next = request.GET.get('state')  # 获取用户界面来源
            response = redirect(next or '/')  # 创建响应对象及重定向
            # 向cookie中设置username以备在状态栏显示用户的用户名
            response.set_cookie('username', user.username, max_age=300)
            # 在此处就作合并购物车
            merge_cart_cookie_to_redis(request, response)
            # 4.响应
            return response
Exemple #23
0
    def post(self, request):
        # 根据用户传递来的手机号,判断用户是否注册美多商城账号
        user_info = json.loads(request.body.decode())
        mobile = user_info.get('mobile')
        password = user_info.get('password')
        sms_code = user_info.get('sms_code')
        access_token = user_info.get("access_token")

        if not all([mobile, password, sms_code, access_token]):
            return JsonResponse({'code': 400, 'errmsg': '缺少参数'})

        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400, 'errmsg': '请输入正确的手机号码'})

        # 判断密码是否合格
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return JsonResponse({'code': 400, 'errmsg': '请输入8-20位的密码'})

        conn = get_redis_connection('sms_code')
        sms_code_fron_redis = conn.get('sms_%s' % mobile)
        if not sms_code_fron_redis:
            return JsonResponse({'code': 400, 'errmsg': '验证码过期'})
        if sms_code_fron_redis.decode() != sms_code:
            return JsonResponse({'code': 400, 'errmsg': '您输入的短信验证码有误!'})

        # 把openid从access_token参数中解密出来
        openid = check_access_token(access_token)
        # ===============================================
        #         不绑定的两种情况
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist as e:
            print(e)
            # 1、没有注册,新建再绑定
            user = User.objects.create_user(username=mobile,
                                            mobile=mobile,
                                            password=password)
            # 绑定openid
            OAuthQQUser.objects.create(openid=openid, user=user)

            login(request, user)
            response = JsonResponse({'code': 0, 'errmsg': 'ok'})
            response.set_cookie('username',
                                user.username,
                                max_age=3600 * 24 * 14)
            response = merge_cart_cookie_to_redis(request, user, response)
            return response

        # 2、已经注册,直接绑定
        # 绑定openid
        OAuthQQUser.objects.create(openid=openid, user=user)
        login(request, user)
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
        response = merge_cart_cookie_to_redis(request, user, response)
        return response
Exemple #24
0
    def post(self, request, *args, **kwargs):
        response = super(UserAuthorizeView, self).post(request, *args, **kwargs)
        serializer = self.get_serializer(data=request.data)

        if serializer.is_valid():
            user = serializer.object.get('user') or request.user
            merge_cart_cookie_to_redis(request, response, user)

        return response
Exemple #25
0
    def get(self, request):
        """Oauth2.0认证"""
        # 接收Authorization Code
        code = request.GET.get('code')

        if not code:
            return 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)

            # 使用access_token向QQ服务器请求openid
            openid = oauth.get_open_id(access_token)

        except Exception as e:
            logger.error(e)

            return HttpResponseServerError("OAuth2.0认证失败")

        try:
            oauth_user = OAuthQQUser.objects.get(openid=openid)

        except OAuthQQUser.DoesNotExist:

            # 如果openid没绑过美多商城用户
            openid = generate_openid_signature(openid)
            context = {'openid': openid}
            return render(request, 'oauth_callback.html', context)

        else:

            # 如果已经绑定过美多商城用户
            qq_user = oauth_user.user
            login(request, qq_user)

            # 响应结果

            # 获取界面跳转来源

            response = redirect(request.GET.get('state') or "/")

            # 登录时用户名写入到cookie,有效期15天
            response.set_cookie('username', qq_user.username, max_age=3600 * 24 * 14)

            merge_cart_cookie_to_redis(request, response)

            return response
    def post(self, request):
        # 1、提取参数
        data = json.loads(request.body.decode())
        mobile = data.get('mobile')
        password = data.get('password')
        sms_code = data.get('sms_code')
        access_token = data.get('access_token')  # 加密的{"openid": "123456789"}

        # 2、校验参数
        # 2.1、必要性校验
        if not all([mobile, password, sms_code, access_token]):
            return JsonResponse({'code': 400, 'errmsg': '缺少必要参数'})
        # 2.2、约束性校验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400, 'errmsg': '手机号格式有误'})
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return JsonResponse({'code': 400, 'errmsg': '密码格式有误'})
        # 2.3、业务性校验
        conn = get_redis_connection('verify_code')
        sms_code_from_redis = conn.get('sms_%s' % mobile)
        if not sms_code_from_redis:
            return JsonResponse({'code': 400, 'errmsg': '短信验证码过期'})
        if sms_code != sms_code_from_redis.decode():
            return JsonResponse({'code': 400, 'errmsg': '短信验证码输入错误'})

        # 3、业务数据处理 —— 绑定账号
        # 3.1、解密openid
        data_dict = SecretOauth().loads(
            access_token)  # {"openid": "1234567890"} or None
        if not data_dict:
            return JsonResponse({'code': 400, 'errmsg': 'openid有误!'})
        openid = data_dict.get('openid')
        # 3.2、根据用户传递的手机号查找用户对象
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist as e:
            # 未注册美多账号  —— 新建绑定
            user = User.objects.create_user(username=mobile,
                                            mobile=mobile,
                                            password=password)
        else:
            # 注册过美多账号  —— 直接绑定
            if not user.check_password(password):
                return JsonResponse({'code': 400, 'errmsg': '密码错误'})

        # 绑定
        OAuthQQUser.objects.create(user=user, openid=openid)

        # 4、构建响应
        login(request, user)
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
        # TODO: 合并购物车
        merge_cart_cookie_to_redis(request, response)
        return response
Exemple #27
0
    def post(self, request):
        # 获取表单数据
        query_dict = request.POST
        username = query_dict.get('username')
        password = query_dict.get('pwd')
        remembered = query_dict.get('remembered')

        # 校验数据
        if all([username, password]) is None:
            return HttpResponseForbidden("缺少必要的参数")

        if not re.match('^[a-zA-Z0-9_-]{5,20}$', username):
            return render(request, 'login.html', {'loginerror': '帐号或密码错误'})

        if not re.match('^[0-9A-Za-z]{8,20}$', password):
            return render(request, 'login.html', {'loginerror': '帐号或密码错误'})

        # 多帐号登录功能实现
        # try:
        #     user = User.objects.get(username=username)
        # except User.DoesNotExist:
        #     try:
        #         user = User.objects.get(mobile=username)
        #     except User.DoesNotExist:
        #         return render(request, 'login.html', {'account_errmsg': '帐号或密码错误'})
        #
        # if user.check_password(password) is False:
        #     return render(request, 'login.html', {'account_errmsg': '帐号或密码错误'})

        # 用户认证    authenticate(请求对象, 认证参数), 查询不到用户返回None
        user = authenticate(request, username=username, password=password)
        if user is None:
            return render(request, 'login.html', {'loginerror': '帐号或密码错误'})

        # 状态保持
        login(request, user)
        if remembered is None:
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(settings.SESSION_COOKIE_AGE)

        # response = redirect('/')
        # 根据查询参数next的值重定向
        response = redirect(request.GET.get('next') or '/')

        merge_cart_cookie_to_redis(request, response)

        # 设置cookie
        response.set_cookie(
            'username',
            user.username,
            max_age=settings.SESSION_COOKIE_AGE if remembered else None)

        return response
Exemple #28
0
    def get(self, request):
        """提取code请求参数"""
        code = request.query_params.get('code')
        if not code:
            return Response({'message': '缺少code的值'},
                            status=status.HTTP_400_BAD_REQUEST)
        # 1.1 创建qq登录工具对象
        oauthqq = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                          client_secret=settings.QQ_CLIENT_SECRET,
                          redirect_uri=settings.QQ_REDIRECT_URI)

        try:
            # 2.通过code向QQ服务器请求获取access_token
            access_token = oauthqq.get_access_token(code)
            # 3.通过access_token向QQ服务器请求获取openid
            openid = oauthqq.get_open_id(access_token)
        except Exception as e:
            logger.info(e)
            return Response({'message': 'QQ服务器异常'},
                            status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 4.查询openid是否绑定过美多商城中的用户
        try:
            qqauth_model = QQAuthUser.objects.get(openid=openid)
        except QQAuthUser.DoesNotExist:
            # 如果qqauth_model异常,说明用户没有进行过QQ登录,
            # 如果openid没有绑定过美多商城中的用户
            # 把openid进行加密安全处理,再响应给浏览器,让它先帮我们保存一会

            openid_save = generate_save_user_token(openid)
            return Response({'access_token': openid_save})

        else:
            # 如果openid已经绑定过美多商城中的用户(生成jwt token直接让它登录成功)
            # 手动生成token
            # QQ登录的状态保持
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER  # 加载生成载荷函数
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER  # 加载生成token函数

            user = qqauth_model.user  #  通过第三方QQ的数据的用户获取user(user是外键,可以得到User)
            payload = jwt_payload_handler(user)  # 生成载荷
            token = jwt_encode_handler(payload)  # 根据载荷生成token

            # 返回值
            response = Response({
                'token': token,
                'username': user.username,
                'user_id': user.id,
            })

            # 做cookie购物车合并到redis操作
            merge_cart_cookie_to_redis(request, user, response)

            return response
Exemple #29
0
    def post(self, request):
        """用户注册功能"""

        # 接收前端传入的表单数据: username, password, password2, mobile, sms_code, allow
        username = request.POST.get('username')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        mobile = request.POST.get('mobile')
        sms_code = request.POST.get('sms_code')
        allow = request.POST.get('allow')  # 单选框如果勾选就是 'on',如果没有勾选 None

        #  all None, False, ''
        # 校验前端传入的参数是否齐全
        if all([username, password, password2, mobile, sms_code, allow]) is False:
            return http.HttpResponseForbidden('缺少必传参数')

        # 校验数据前端传入数据是否符合要求
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseForbidden('请输入5-20个字符的用户名')

        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('请输入8-20位的密码')

        if password != password2:
            return http.HttpResponseForbidden('输入的密码两次不一致')

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('您输入的手机号格式不正确')

        # 短信验证码校验后期再补充
        redis_coon = get_redis_connection('verify_code')
        sms_code_server = redis_coon.get('sms_%s' % mobile)  # 获取redis中的短信验证码

        if sms_code_server is None or sms_code != sms_code_server.decode():
            return http.HttpResponseForbidden('短信验证码有误')

        # 创建一个user
        try:
            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)  # 存储用户的id到session中记录它的登录状态
        response = redirect('/')  # 创建好响应对象
        response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE)
        merge_cart_cookie_to_redis(request, response)
        # 响应结果重定向到首页
        return response
    def post(self, request):
        # 1.接收表单数据
        query_dict = request.POST
        mobile = query_dict.get('mobile')
        password = query_dict.get('password')
        sms_code = query_dict.get('sms_code')
        openid = query_dict.get('openid')

        # 校验
        if all([mobile, password, sms_code, openid]) is False:
            return http.HttpResponseForbidden('缺少必传参数')

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入5-20个字符的用户名')
        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)
        redis_conn.delete('sms_%s' % mobile)

        if sms_code_server is None:
            return http.HttpResponseForbidden('短信验证码过期')
        sms_code_server = sms_code_server.decode()
        if sms_code != sms_code_server:
            return http.HttpResponseForbidden('请输入正确的短信验证码')

        openid = check_openid_signature(openid)
        if openid is None:
            return http.HttpResponseForbidden('openid无效')

        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            user = User.objects.create_user(mobile=mobile,
                                            password=password,
                                            username=mobile)
        else:
            if user.check_password(password) is False:
                return render(request, 'oauth_callback.html',
                              {'account_errmsg': '用户名或密码错误'})
        # openid和用户绑定
        OAuthQQuser.objects.create(openid=openid, user=user)

        login(request, user)
        next = request.GET.get('state')
        response = redirect(next or '/')
        response.set_cookie('username',
                            user.username,
                            max_age=settings.SESSION_COOKIE_AGE)

        # 在此就做合并购物车
        merge_cart_cookie_to_redis(request, response)
        return response
Exemple #31
0
    def post(self, request):
        """
        实现登录逻辑
        :param request:请求对象
        :return: 登录结果
        """
        # 1.接收参数
        username = request.POST.get('username')
        password = request.POST.get('password')
        remembered = request.POST.get('remembered')

        # 2.校验参数
        # 判断参数是否齐全
        # 这里注意:remembered 这个参数可以是 None 或者是 ‘no’
        # 所以我们不对它是否存在进行判断
        if not all([username, password]):
            return http.HttpResponseForbidden('缺少必传参数')

        # 判断用户名是否是5-20个字符
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseForbidden('请输入正确的用户名或手机号')

        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('密码最少8位,最长20位')

        # 认证登录用户 authenticate 是django自带的认证用户方法,返回用户名
        user = authenticate(username=username, password=password)
        if user is None:
            return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'})

        # 实现状态保持
        login(request, user)
        # 设置状态保持的周期
        if remembered != 'on':
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(None)

        # 获取跳转过来的地址
        next = request.GET.get('next')

        # 判断参数是否存在
        if next:
            # 如果是从别的页面跳转过来的, 则重新跳转到原来的页面
            response = redirect(next)
        else:
            # 生成响应对象
            # 如果不是从别的页面跳转过来的,就重定向到首页
            response = redirect(reverse('contents:index'))
        # 在响应对象中设置用户名信息
        # 将用户名写入到 cookie,有效期15天
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)

        # 合并购物车
        response = merge_cart_cookie_to_redis(request, user, response)
        # 返回响应结果
        return response
Exemple #32
0
    def get(self, request):
        """Oauth2.0认证"""
        # 接收Authorization 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)

            # 携带 access_token 向 QQ服务器 请求 openid
            openid = oauth.get_open_id(access_token)

        except Exception as e:
            # 如果上面获取 openid 出错, 则验证失败
            logger.error(e)
            # 返回结果
            return http.HttpResponseServerError('OAuth2.0认证失败')

        try:
            oauth_user = OAuthQQUser.objects.get(openid=openid)

        except OAuthQQUser.DoesNotExist:
            # 如果 openid 没绑定美多商城用户,进入这里:
            # 调用我们封装好的方法, 对 openid 进行加密, 生成 access_token 字符串
            access_token = generate_access_token(openid)
            # 拿到 access_token 字符串后, 拼接字典
            context = {'access_token': access_token}
            # 返回响应, 重新渲染
            return render(request,'oauth_callback.html', context)

        else:
            # 如果 openid 已绑定美多商城用户
            # 根据 user 外键, 获取对应的 QQ用户
            qq_user = oauth_user.user
            # 实现状态保持
            login(request, qq_user)

            # 创建重定向到主页的对象
            response = redirect(reverse('contents:index'))

            # 将用户信息写入到 cookie 中,有效期15天
            response.set_cookie('username',qq_user.username,max_age=3600 * 24 * 15)

            # 合并购物车
            response = merge_cart_cookie_to_redis(request=request, user=qq_user, response=response)

            # 返回响应
            return response
Exemple #33
0
    def post(self, request):
        """美多商城用户绑定到openid"""

        # 1.接收参数
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        sms_code_client = request.POST.get('sms_code')
        access_token = request.POST.get('access_token')

        # 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位密码')

        # 3.判断短信验证码是否一致
        # 创建 redis 链接对象:
        redis_conn = get_redis_connection('verify_code')
        # 从 redis 中获取 sms_code 值:
        sms_code_server = redis_conn.get('sms_code_%s' % mobile)
        print(sms_code_server)
        # 判断获取出来的有没有
        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': '输入的短信验证码有误'})
        # 调用我们自定义的函数, 检验传入的 access_token 是否正确:
        # 错误提示放在 sms_code_errmsg 位置
        openid = check_access_token(access_token)

        if openid is None:
            return render(request, 'oauth_callback.html', {'openid_errmsg': '无效的openid'})

        # 4.保存注册数据
        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': '用户名或密码错误'})

        # 5.将用户绑定 openid
        try:
            OAuthQQUser.objects.create(openid=openid, user=user)
        except DatabaseError:
            return render(request, 'oauth_callback.html', {'qq_login_errmsg': 'QQ登录失败'})

        # 6.实现状态保持
        login(request, user)

        # 7.响应绑定结果
        next = request.GET.get('next', '/')
        response = redirect(next)

        # 8.登录是用户名写入到 cookid, 有效期 15天
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)

        # 合并购物车
        response = merge_cart_cookie_to_redis(request, user, response)
        # 9.返回(从哪里来到那里去)
        return response