Header.vue组件代码:
实现的思路:头部子组件是通过token值进行判断登录状态,所以当用户点击"退出登录",则需要移出token的值,并使用elementUI里面的弹窗组件进行提示。
Header.vue组件代码:
{{nav.name}} 0 购物车 学习中心 我的账户 我的订单 我的优惠卷 退出登录 购物车 登录 |注册
官网: 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()), ]
客户端发送注册信息和发送短信
注册路飞学城{{get_sms_text}}已有账号
直接登录