在之前的blog里,我们已经将整个Django框架搭建了起来,并且已经实现了【登录/注册/注销】等功能
那这篇呢,咱们主要实现 【验证码登录】 的功能,第三方我们这里对接 【网易云信】,当然短信对接你也可以用 阿里云 哈~
- ps:以前打Java项目的时候已经把阿里云的免费短信用完了,这次
到时候我会把第三方发送短信的个人信息部分给码掉,大家自己去【网易云信】注册账号填写自己的信息即可,以下内容部分我会详细介绍一下
环境:
- Pycharm
- python3.6
- mysql 5.7
- django 2.0.13
一、网易云信使用介绍 1、网易云信注册及短信开通
-
由于我们需要对接第三方网易云信,那么首先大家需要先去网易云信注册一个账号,登录后进入首页,并且创建一个自己的应用,然后再申请试用短信
网易云信注册地址:https://id.grow.163.com/register?h=media&t=media&from=nim%7Chttps%3A%2F%2Fdoc.yunxin.163.com%2Fdocs%2FDI1Mzc2NTU%2Fjg2NDEyMzI&clueFrom=nim&referrer=https%3A%2F%2Fapp.yunxin.163.com
2、网易云信短信API简要介绍
-
【网易云信短信API】具体地址如下,大家点击进去阅览即可,到时候写代码的时候根据第三方提供的接口规范来写就可以了
网易云信短信API对接:https://doc.yunxin.163.com/docs/DI1Mzc2NTU/jg2NDEyMzI?platformId=120002
短信API请求头概述:https://doc.yunxin.163.com/docs/TM5MzM5Njk/jk3MzY2MTI?platformId=60353
短信API返回状态码概述:
https://doc.yunxin.163.com/docs/TM5MzM5Njk/Tk5ODIzNjk?platformId=60353
二、新增功能项目概览
- 这个界面大家可以自行再优化一下样式,加上发送后倒计时60s的效果都可以,我这里就没做了…
logo图片我这里是让公司的UI同事给调成透明的,大家可以自行去网站设计logo哈
三、Templates模块具体实现
-
以上的准备工作已经做好了,那么我们从这part就详细讲述下 【验证码登录】 功能的具体实现,上面我也简要介绍了一下网易云信的使用和介绍,那咱们这里废话不多说,就直接代码开整了,大家若是有什么疑问可以在评论区或者私信询问我~
-
页面这part我稍微把之前的登录界面login.html优化了一下
- 这里主要就是一个验证码登录界面,js部分则实现点击发送验证码按钮,发送ajax请求,并将返回结果页面显示
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
短信验证码登录
{% endblock %}
{# css样式部分 #}
{% block mycss %}
{% endblock %}
{# 内容部分 #}
{% block content %}
{% endblock %}
{# js 部分#}
{% block myjs %}
{% endblock %}
2、login.html
- login页面只是进行了小优化,加了个验证码登录的a标签
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
用户登录
{% endblock %}
{# css样式部分 #}
{% block mycss %}
{% endblock %}
{# 内容部分 #}
{% block content %}
{% endblock %}
四、user模块具体实现 1、新增utils.py
- utils:即工具类,我们将项目需要的一些工具方法统一在这个类里面定义,那这里的话,我是把调用第三方发送短信验证码的方法写在了这里
"""
该类为工具类
里面封装:发送短信等..
"""
import hashlib
import json
from time import time
import requests
def send_api(req, tools="requests"):
"""
封装发送请求工具(可以使用urlib3/requests)
:param tools:
:param req:
:return:
"""
if tools == "requests":
return requests.request(**req)
def send_msg(mobile):
"""
第三方接口:网易云信,发送短信验证码
:param mobile: 手机号
:return:
"""
# 请求头四部分组成 AppKey + CurTime + CheckSum + Nonce
AppKey = '拿你自己的应用的appkey' # 拿你的应用的appkey
Nonce = 'mikasa' # 随机数(不大于128即可)
CurTime = str(int((time() * 1000))) # 采用时间戳
AppSecret = '拿你自己的应用的appSecret' # 拿你的应用的appSecret
# SHA1(AppSecret + Nonce + CurTime),三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写)
content = AppSecret + Nonce + CurTime
CheckSum = hashlib.sha1(content.encode('utf-8')).hexdigest()
req = {
"method": "POST",
"url": 'https://api.netease.im/sms/sendcode.action',
"headers": {
'AppKey': AppKey,
'Nonce': Nonce,
'CurTime': CurTime,
'CheckSum': CheckSum,
'Content-Type': 'application/x-www-form-urlencoded'
},
"data": {
'mobile': mobile
}
}
print("req:", req)
res = send_api(req)
print("第三方响应结果:", res.json())
return res.json()
2、urls.py
- 这里就添加【发送手机验证码】和【验证码登录】的两路由
"""
用户相关的路径
"""
from django.urls import path
from user.views import user_register, user_login, user_logout, code_login, send_code
urlpatterns = [
# 注册
path('register', user_register, name='register'),
# 登录
path('login', user_login, name='login'),
# 注销
path('logout', user_logout, name='logout'),
# 发送手机验证码
path('send_code', send_code, name='send_code'),
# 验证码登录
path('codelogin', code_login, name='codelogin'),
]
3、views.py
- 这里添加两视图函数
from django.urls import reverse
from user import utils
from user.forms import RegisterForm, LoginForm
from user.models import UserProfile
"""
视图函数
"""
def send_code(request):
"""
发送短信验证码:调用第三方网易云信
:param request:
:return:
"""
# 1、获取到填写的手机号
mobile = request.GET.get("mobile")
data = {}
if UserProfile.objects.filter(mobile=mobile).exists():
# 2、判断手机号是否存在,存在则发送验证码给第三方,并拿到返回结果
json_result = utils.send_msg(mobile)
status = json_result.get("code")
# 3、封装一下网易云信的返回信息
if status == 200:
check_code = json_result.get('obj')
# 把验证码保存在session里面
request.session['msg_code'] = check_code
data['status'] = 200
data['result'] = "验证码发送成功!"
else:
data['status'] = 500
data['result'] = "验证码发送失败!"
else:
data['status'] = 501
data['result'] = "用户不存在"
return JsonResponse(data)
def code_login(request):
"""
手机验证码登录:拿到第三方返回的短信验证码后,与页面输入的验证码进行校验
:param request:
:return:
"""
if request.method == 'GET':
return render(request, 'user/codelogin.html')
else:
# 1、拿到页面表单传的值
mobile = request.POST.get('mobile')
code = request.POST.get('code')
# 2、去session中取到之前存的验证码
check_code = request.session.get('msg_code')
print("正确验证码:", check_code)
# 校验验证码是否正确
if code == check_code:
# 若验证码正确,根据手机号查询数据库
user = UserProfile.objects.filter(mobile=mobile).first()
username = user.username
if user:
# 若用户存在,则登录
login(request, user)
request.session['username'] = username # 拿到数据库里面的username,保存在session中返回给页面显示
return redirect(reverse('index'))
else:
return HttpResponse("验证失败!")
else:
return render(request, 'user/codelogin.html', context={'msg': "验证码有误!"})
五、项目启动及查看



