用户的登陆认证

用户的登陆认证

前端首页实现登陆状态的判断

Header.vue组件代码:

 

头部组件中实现退出登录

实现的思路:头部子组件是通过token值进行判断登录状态,所以当用户点击"退出登录",则需要移出token的值,并使用elementUI里面的弹窗组件进行提示。

Header.vue组件代码:

 

 

在登录认证中接入极验验证

官网: https://www.geetest.com/first_page/

注册登录以后,即进入登录后台,选择行为验证。

 

 

 

接下来,就可以根据官方文档,把验证码集成到项目中了

 

''文档地址:https://docs.geetest.com/install/overview/start/

下载和安装验证码模块包。

git clone https://github.com/GeeTeam/gt3-python-sdk.git

安装依赖模块

pip install requests

 

把验证码模块放置到在libs目录中

users/views.py文件下方:

from rest_framework.views import APIView
from luffy.libs.geetest import GeetestLib
from django.conf import settings
import random
from rest_framework.response import Response
​
class CaptchaAPIView(APIView):
    """极验验证码"""
    def get(self,request):
        """提供生成验证码的配置信息"""
        user_id = '%06d' % random.randint(1,9999)
        gt = GeetestLib(settings.PC_GEETEST_ID, settings.PC_GEETEST_KEY)
        status = gt.pre_process(user_id)
        print(status)
​
        # 把这两段数据不要保存在session里面, 保存到redis里面
        request.session[gt.GT_STATUS_SESSION_KEY] = status
        request.session["user_id"] = user_id
​
        response_str = gt.get_response_str()
        return Response(response_str)
​
    def post(self,request):
        """进行二次验证"""
        pass

users/urls.py路由注册:

path(r'captcha/', views.CaptchaAPIView.as_view() ),

配置文件settings/dev.py代码:

PC_GEETEST_ID = '5f4ab1914455506edffaffd4da37fea5'
PC_GEETEST_KEY ='460e13a49d687e5e44e25c383f0473a6'

 

前端获取显示并校验验证码

把下载会哦图的验证码模块包中的gt.js放置到前端项目中,并在main.js中引入

// 导入gt极验
import '../static/globals/gt.js'

显示验证码

效果:

后端提供二次验证的API接口

from django.shortcuts import render
​
# Create your views here.
from .serializers import UserModelSerializer
from rest_framework.generics import CreateAPIView
from .models import User
class UserAPIView(CreateAPIView):
    serializer_class = UserModelSerializer
    queryset = User.objects.all()
​
​
from rest_framework.views import APIView
from luffy.libs.geetest import GeetestLib
from django.conf import settings
import random
from rest_framework.response import Response
​
class CaptchaAPIView(APIView):
    """极验验证码"""
    gt = GeetestLib(settings.PC_GEETEST_ID, settings.PC_GEETEST_KEY)
    def get(self,request):
        """提供生成验证码的配置信息"""
        user_id = '%06d' % random.randint(1,9999)
        status = self.gt.pre_process(user_id)
        print(status)
​
        # 把这两段数据不要保存在session里面, 保存到redis里面
        request.session[self.gt.GT_STATUS_SESSION_KEY] = status
        request.session["user_id"] = user_id
​
        response_str = self.gt.get_response_str()
        return Response(response_str)
​
    def post(self,request):
        """进行二次验证"""
        challenge = request.data.get(self.gt.FN_CHALLENGE, '')
        validate = request.data.get(self.gt.FN_VALIDATE, '')
        seccode = request.data.get(self.gt.FN_SECCODE, '')
​
        status = request.session.get(self.gt.GT_STATUS_SESSION_KEY)
        user_id = request.session.get("user_id")
​
        if status:
            result = self.gt.success_validate(challenge, validate, seccode, user_id)
        else:
            result = self.gt.failback_validate(challenge, validate, seccode)
​
        # 返回一个随机字符串,在用户登录提供数据时一并发送到后端,进行验证
        # 后面可以使用redis保存
    
​
        return Response({"message":result})

 

Login.vue代码


修改验证码框的样式位置。

static/css/reset.css,代码:

.geetest_holder{
	padding-top: 15px;
	width: 100%!important;
}

 

用户的注册认证

前端显示注册页面并调整首页头部和登陆页面的注册按钮的链接。

注册页面Register,主要是通过登录页面进行改成而成./

前端注册路由:

import Register from "../components/Register"
​
// 配置路由列表
export default new Router({
  mode:"history",
  routes:[
    // 路由列表
    ...
    {
      name:"Register",
      path: "/register",
      component:Register,
    }
  ]
})
​

修改首页头部的连接:

# Header.vue
注册
#Login.vue

 

 

注册功能的实现

接下来,我们把注册过程中一些注册信息(例如:短信验证码)和session缓存到redis数据库中。

安装django-redis。

pip install django-redis

 

在settings.py配置中添加一下代码:

# 设置redis缓存
CACHES = {
    # 默认缓存
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        # 项目上线时,需要调整这里的路径
        "LOCATION": "redis://127.0.0.1:6379/0",
​
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
    # 提供给xadmin或者admin的session存储
    "session": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
    # 提供存储短信验证码
    "sms_code":{
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/2",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}
​
# 设置xadmin用户登录时,登录信息session保存到redis
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "session"

关于django-redis 的使用,说明文档可见http://django-redis-chs.readthedocs.io/zh_CN/latest/

django-redis提供了get_redis_connection的方法,通过调用get_redis_connection方法传递redis的配置名称可获取到redis的连接对象,通过redis连接对象可以执行redis命令

https://redis-py.readthedocs.io/en/latest/

使用范例:

from django_redis import get_redis_connection
// 链接redis数据库
redis_conn = get_redis_connection("default")

 

 

使用云通讯发送短信

在登录后的平台上面获取一下信息:

ACCOUNT SID:8aaf0708697b6beb01699f4442911776
AUTH TOKEN : b4dea244f43a4e0f90e557f0a99c70fa
AppID(默认):8aaf0708697b6beb01699f4442e3177c
Rest URL(生产): app.cloopen.com:8883         [项目上线时使用真实短信发送服务器]
Rest URL(开发): sandboxapp.cloopen.com:8883  [项目开发时使用沙箱短信发送服务器]

找到sdkdemo进行下载

 

在开发过程中,为了节约发送短信的成本,可以把自己的或者同事的手机加入到测试号码中.

 

后端生成短信验证码

from .yuntongxun.sms import CCP
class SMSCodeAPIView(APIView):
    """
    短信验证码
    """
    def get(self, request, mobile):
        """
        短信验证码
        """
        # 生成短信验证码
        sms_code = "%06d" % random.randint(0, 999999)
​
        # 保存短信验证码与发送记录
        redis_conn = get_redis_connection('verify_codes')
        # 使用redis提供的管道操作可以一次性执行多条redis命令
        pl = redis_conn.pipeline()
        pl.multi()
        pl.setex("sms_%s" % mobile, 300, sms_code) # 设置短信有效期为300s
        pl.setex("sms_time_%s" % mobile, 60, 1)    # 设置发送短信间隔为60s
        pl.execute()
​
        # 发送短信验证码
        ccp = CCP()
        ccp.send_template_sms(mobile, [code, "5"], 1)
​
        return Response({"message": "OK"}, status.HTTP_200_OK)

 

后端保存用户注册信息

创建序列化器对象[暂时不涉及到手机验证码功能]

from rest_framework import serializers
from .models import User
import re
class UserModelSerializer(serializers.ModelSerializer):
    """用户信息序列化器"""
    sms_code = serializers.CharField(label='手机验证码', required=True, allow_null=False, allow_blank=False, write_only=True)
    password2 = serializers.CharField(label='确认密码', required=True, allow_null=False, allow_blank=False, write_only=True)
​
    class Meta:
        model=User
        fields = ('sms_code', 'mobile', "username", 'password','password2')
        extra_kwargs={
            "password":{
                "write_only":True
            }
        }
​
    def validate_mobile(self, mobile):
        # 验证格式
        result = re.match('^1[3-9]\d{9}$', mobile)
        if not result:
            raise serializers.ValidationError("手机号码格式有误!")
​
            # 验证唯一性
            try:
                user = User.objects.get(mobile=mobile)
                if user:
                    raise serializers.ValidationError("当前手机号码已经被注册!")
​
                    except User.DoesNotExist:
                        pass
​
                    return mobile
​
    def validate(self,data):
        # 验证密码
        password = data.get("password")
        password2 = data.get("password2")
        if len(password)<6 or len(password) > 16:
            raise serializers.ValidationError('密码长度必须在6-16位之间~')
​
        if password != password2:
            raise serializers.ValidationError('密码和确认必须一致~')
​
        return data
​
    def create(self, validated_data):
        # 删除一些不需要保存到数据库里面的字段
        del validated_data['password2']
        del validated_data['sms_code']
        
        # 因为数据库中默认用户名是唯一的,所以我们把用户手机号码作为用户名
        validated_data["username"] = validated_data["mobile"]
        
        # 继续调用ModelSerializer内置的添加数据功能
        user = super().create(validated_data)
​
        # 针对密码要加密
        user.set_password(user.password)
        # 修改密码等用于更新了密码,所以需要保存
        user.save()
​
        return user

视图代码:

# users/views.py
from rest_framework.generics import CreateAPIView
from .models import User
from .serializers import UserModelSerializer
class UserAPIView(CreateAPIView):
    """用户管理"""
    queryset = User.objects.all()
    serializer_class = UserModelSerializer

 

设置路由

# 子应用路由 urls.py
urlpatterns=[
	...
    path(r"user", views.UserAPIView.as_view()),
]

 

客户端发送注册信息和发送短信







 

你可能感兴趣的:(用户的登陆认证)