首页 > 技术文章 > DRF 中使用 级验科技滑动验证

zhang-zi-yi 2019-02-27 22:14 原文

接口的login 登录

  • 使用 Django 中的 auth 认证 因为之前合并了 django 的 用户表 创建的 用户 密码 会在内部进行加密 不知道加密方式所以要使用 authenticate 来进行判断

  • 使用 APIView 自定义一个 视图

导入 认证
from django.contrib.auth import authenticate

使用 自带的 认证来判断用户名跟密码
class LoginView(APIView):
    def post(self, request):
        res_obj = MyResponse()  # 使用自定义的 响应对象
        username, password = request.data.get('username'), request.data.get('password')
        auth_obj = authenticate(username=username,password=password)
        if auth_obj:
            res_obj.data = '登陆成功!'
        else:
            res_obj.data = '账号或密码错误!'
        # logger.debug(request.data)
        return Response(res_obj.dict)
  • 可以使用邮箱登录

    from django.contrib.auth import authenticate, login, logout
    from django.contrib.auth.backends import ModelBackend
    from django.db.models import Q
    from models import UserProfile
    
    # 让用户可以用邮箱登录
    # setting 里要有对应的配置
    class CustomBackend(ModelBackend):
        def authenticate(self, username=None, password=None, **kwargs):
            try:
                user = UserProfile.objects.get(Q(username = username) | Q(email=username))
                if user.check_password(password):
                    return user
            except Exception as e:
                return None
    复制代码
    记得引入models中创建的表
    
    # AUTH 方法(支持邮箱登录)
    AUTHENTICATION_BACKENDS = ('users.views.CustomBackend',)
    

级验科技滑动验证

  1. 注意官方文档 学习使用 SDK 并下载 匹配使用 的 SDK

  2. 后端 创建 对应的 返回 初始化滑动验证 的 json 数据

    from django.shortcuts import HttpResponse
    # 从 SDK的  \gt3-python-sdk-master\sdk  中 查找  工具类 
    from utils.geetest import GeetestLib
    
    # 请在官网申请ID使用,示例ID不可使用
    pc_geetest_id = "b46d1900d0a894591916ea94ea91bd2c"
    pc_geetest_key = "36fc3fe98530eea08dfc6ce76e3d24c4"
    
    # 页面初始化时请求的 数据
    def pcgetcaptcha(request):
        user_id = 'test'
        gt = GeetestLib(pc_geetest_id, pc_geetest_key)
        status = gt.pre_process(user_id)
        # 前后端分离的  项目  永不到  
        # request.session[gt.GT_STATUS_SESSION_KEY] = status    
        # request.session["user_id"] = user_id
        response_str = gt.get_response_str()
        return HttpResponse(response_str)
    
    
  3. 从前端 接收 对应的 数据

    //  导入 必须的js文件  从sdk 文档中 查找 
    import '@/assets/js/gt'
    
    created() {
        this.$axios.get('/pcgetcaptcha/')
            .then((res) => {
            console.log(res);
            //请检测data的数据结构, 保证data.gt, data.challenge, data.success有值
            let data = res.data;
            initGeetest({
                // 以下配置参数来自服务端 SDK
                gt: data.gt,
                challenge: data.challenge,
                offline: !data.success,
                new_captcha: true,
                // product: 'popup',  // 选项:  float、popup、custom、bind
            }, function (captchaObj) {
                // 这里可以调用验证实例 captchaObj 的实例方法
                captchaObj.appendTo("#captchaBox"); 
                //将验证按钮插入到宿主页面中captchaBox元素内  id 选择器
            })
        })
    },
    
  4. 二次 验证 前端 发送 登录请求 并且携带着 滑动验证的 参数

    注意:

    • validateResult 是包存在 组件中的 data 数据 在 通过滑动验证时执行的函数 需要注意 this 的指向问题 通过 在 外部定义变量来保存 this 对象
    methods: {
        // 登录的 点击按钮
        login_btn() {
            this.$axios.post('/login/', {
                username: this.username,
                password: this.password,
                // 滑动验证 相应的 参数
                geetest_challenge: this.validateResult.geetest_challenge,
                geetest_validate: this.validateResult.geetest_validate,
                geetest_seccode: this.validateResult.geetest_seccode,
            })
                .then((res) => {
                if (res.data.code === 0) {
                    this.$router.push({name: 'home'})
                } else {
                    alert(res.data.error)
                }
            })
        }
    },
        created() {
            this.$axios.get('/pcgetcaptcha/')
                .then((res) => {
                // 定义变量 保存 this 指向
                let base = this;
                //请检测data的数据结构, 保证data.gt, data.challenge, data.success有值\
                let data = res.data;
                initGeetest({
                    // 以下配置参数来自服务端 SDK
                    gt: data.gt,
                    challenge: data.challenge,
                    offline: !data.success,
                    new_captcha: true,
                    // product: 'popup',  // 选项:  float、popup、custom、bind
                }, function (captchaObj) { // 这里可以调用验证实例 captchaObj 的实例方法
                    //将验证按钮插入到宿主页面中captchaBox元素内  	id 选择器
                    captchaObj.appendTo("#captchaBox");
                    captchaObj.onReady(function () {
                        // 加载完验证控件之后 执行
                    }).onSuccess(function () {
                        // 验证成功之后 执行
                        let result = captchaObj.getValidate();
                        console.log(result);
                        base.validateResult = result;
                    }).onError(function () {
                        // console.log(3333)
                        //your code
                    }) }) })},
    
  5. 在视图中 接收 用户信息 以及 滑动验证的 数据

    class LoginView(APIView):
        def post(self, request):
            res_obj = MyResponse()
            # 用于滑动验证
            gt = GeetestLib(pc_geetest_id, pc_geetest_key)
            challenge = request.data.get(gt.FN_CHALLENGE, '')
            validate = request.data.get(gt.FN_VALIDATE, '')
            seccode = request.data.get(gt.FN_SECCODE, '')
            status = True   # 前后端分离  没有session 数据 改为 True
            if status:
                # 通过 级验科技验证
                result = gt.success_validate(challenge, validate, seccode, None)
            else:
                # 通过本地验证
                result = gt.failback_validate(challenge, validate, seccode)
            if result:  # 判断是否是真人  还是爬虫
                # 常规用户登录的 数据验证
                username, password = request.data.get('username'), request.data.get('password')
                auth_obj = authenticate(username=username,password=password)
                if auth_obj:
                    res_obj.data = '登陆成功!'
                else:
                    res_obj.error = '账号或密码错误!'
                    res_obj.code = 1
            else:
                # 滑动验证不通过
                res_obj.code = 1
                res_obj.error = '必须通过滑动验证!'
            return Response(res_obj.dict)
    
    

推荐阅读