下面将详细讲解使用Django Rest Framework(DRF)实现一次性验证码OTP的完整攻略。
总体思路
实现一次性验证码OTP的基本思路如下:
- 用户请求获取一次性验证码,并提交验证手机号码(或邮箱等)。
- 服务器生成一个随机验证码和一个有效期,然后将验证码与手机号码或者邮箱进行绑定,存储到后端数据库中。
- 服务器将验证码发送给用户终端。
- 用户获取验证码并提交给服务器进行验证。
- 服务器根据提交的手机号码或者邮箱,查询后端数据库中的验证码和有效期,并进行比对。
- 如果验证码有效,则完成验证码验证。
详细步骤
1. 安装 DRF
使用 pip 安装 DRF:
pip install djangorestframework
2. 实现验证码的生成和绑定
创建一个新的模型类 OTPCode
,用于存储验证码及其对应的手机号码或者邮箱以及有效期等信息:
from django.db import models
class OTPCode(models.Model):
code = models.CharField(max_length=8, unique=True)
phone_number = models.CharField(max_length=11, unique=True)
expire_time = models.DateTimeField()
接下来,实现一个生成验证码的视图函数 generate_code
:
import random
import datetime
from django.utils import timezone
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import OTPCode
@api_view(['POST'])
def generate_code(request):
phone_number = request.data.get('phone_number')
if not phone_number:
return Response(status=400, data={'detail': 'Invalid phone number.'})
code = ''.join([str(random.randint(0, 9)) for _ in range(8)])
expire_time = timezone.now() + datetime.timedelta(minutes=5)
otpcode = OTPCode(code=code, phone_number=phone_number, expire_time=expire_time)
otpcode.save()
return Response(data={'code': code})
这个视图函数首先从请求参数中获取手机号码,然后生成八位数的随机验证码,并设置验证码的有效期为五分钟后。然后将生成的验证码与手机号码进行绑定,并将其存储到 OTPCode
模型中。最后返回验证码给前端。
3. 实现验证码的发送
接下来,我们需要编写一个发送验证码的函数,这里以使用阿里云短信服务为例:
import json
import requests
def send_sms(mobile, code):
url = "https://dysmsapi.aliyuncs.com/"
access_key_id = "<AccessKeyId>"
access_secret = "<AccessSecret>"
sign_name = "<SignName>"
template_code = "<TemplateCode>"
data = {
"PhoneNumbers": mobile,
"SignName": sign_name,
"TemplateCode": template_code,
"TemplateParam": json.dumps({"code": code})
}
headers = {
"content-type": "application/json",
"accept": "application/json",
"method": "POST",
"x-sdk-client": "Python/2.7.5",
}
r = requests.post(url, headers=headers, data=json.dumps(data))
return r.json()
这个函数首先需要设置阿里云短信服务的相关参数,然后使用 requests 库进行 http 请求,将短信发送给用户终端。
4. 实现验证码的验证
接下来,实现根据提交的手机号码验证验证码的视图函数 verify_code
:
@api_view(['POST'])
def verify_code(request):
phone_number = request.data.get('phone_number')
code = request.data.get('code')
if not phone_number or not code:
return Response(status=400, data={'detail': 'Invalid phone number or code.'})
otpcode = OTPCode.objects.filter(phone_number=phone_number).order_by('-expire_time').first()
if not otpcode or otpcode.code != code or otpcode.expire_time < timezone.now():
return Response(status=401, data={'detail': 'Invalid code.'})
return Response(status=200, data={'detail': 'Valid code.'})
这个视图函数首先从请求参数中获取手机号码和验证码,然后根据手机号码查询最近一个有效期内的验证码记录,如果记录不存在或验证码不匹配或验证码已过期,则验证失败,返回 401 状态码;否则,验证成功,返回 200 状态码。
5. 测试发送和验证验证码
可以使用 Postman 或者 curl 等工具,发送 POST 请求进行测试。例如,对于发送验证码,可以使用以下命令:
curl -X POST -H "Content-Type: application/json" -d '{"phone_number": "15000000000"}' http://localhost:8000/api/v1/generate_code/
接收到响应后,可以取出响应的 code
字段,使用以下命令发送验证码:
curl -X POST -H "Content-Type: application/json" -d '{"phone_number": "15000000000", "code": "12345678"}' http://localhost:8000/api/v1/verify_code/
如果验证码验证成功,则响应的状态码应该为 200。
示例说明
示例1
对于一个网站,用户需要绑定手机号码才能完成注册,我们可以在注册页面添加一个发送验证码的按钮。当用户点击该按钮时,后端服务自动生成验证码,并将验证码通过短信的形式发送给用户的手机上。
用户收到验证码后,在注册页面中输入验证码并提交注册信息。后端服务接收到验证码的值后,与之前绑定手机号码的验证码进行比对,如果验证码正确,则允许用户完成注册,否则不允许注册。
示例2
另一个例子是:在忘记密码的情况下,用户可以通过手机号码或邮箱地址来重置密码。当用户提交重置密码请求时,后端服务自动生成一次性验证码,并将验证码发送到用户手机号码或邮箱地址上。
用户输入收到的验证码后,提交重置密码请求。后端服务接收到验证码的值后,与之前绑定手机号码或邮箱地址的验证码进行比对,如果验证码正确,则允许用户重置密码,否则不允许重置。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python编程使用DRF实现一次性验证码OTP - Python技术站