vue_drf 문자 인증 코드 구현
1,수요
우리 가 사이트 개발 을 할 때 로그 인 페이지 의 많은 상황 에서 핸드폰 번호 로 문자 인증 코드 를 받 은 후에 로그 인 을 실현 할 수 있다.그러면 우 리 는 오늘 이 기능 을 하 겠 다.
의사 코드:
로그 인 페이지 에 들 어가 문자 로 로그 인
핸드폰 번 호 를 입력 하고 인증 코드 를 가 져 오 려 면 누 르 십시오.백 엔 드 는 redis 에 인증 코드 를 저장 합 니 다.
사용 자 는 핸드폰 으로 받 은 인증 번 호 를 입력 하고 로그 인 을 클릭 하면 핸드폰 번호 와 인증 번 호 를 백 엔 드 로 보 내 고 검증 을 한다.
문 자 를 보 내 고 사용자 에 게 문 자 를 받 게 하려 면 저 희 는 용 련 클 라 우 드 의 인 터 페 이 스 를 통 해 계 정 을 등록 합 니 다.
사용 시 필요 한 인자:
sdk 다운로드
1.。。。。。。。
2.。。。。。。
3.。。。。。。。
다운로드 완료 후 압축 해제.우리 drf 프로젝트 의 apps 에 libs 를 넣 습 니 다.
2.sdk 매개 변수 설정
1.디 렉 터 리 구조
2,sms.py 파일 설정
# -*- coding:utf-8 -*-
from .CCPRestSDK import REST
# : , , " - " ACCOUNT SID
_accountSid = 'xxxxxxxxxxxxx'
# 8a216da863f8e6c20164139687e80c1b
# : Token, , - AUTH TOKEN
_accountToken = 'xxxxxxxxxxxxx'
# 6dd01b2b60104b3dbc88b2b74158bac6
# APPID APPID
_appId = '8aaf0708697b6beb01699f3c645f1766'
# 8a216da863f8e6c20164139688400c21
# : , app.cloopen.com
_serverIP = 'sandboxapp.cloopen.com'
# : , 8883
_serverPort = "8883"
# :REST API
_softVersion = '2013-12-26'
#
class CCP(object):
""" """
def __new__(cls, *args, **kwargs):
# _instance,_instance CCP ,
if not hasattr(CCP, "_instance"):
cls._instance = super(CCP, cls).__new__(cls, *args, **kwargs)
cls._instance.rest = REST(_serverIP, _serverPort, _softVersion)
cls._instance.rest.setAccount(_accountSid, _accountToken)
cls._instance.rest.setAppId(_appId)
return cls._instance
def send_template_sms(self, to, datas, temp_id):
""" """
# @param to
# @param datas :{'12','34'}, ''
# @param temp_id Id
result = self.rest.sendTemplateSMS(to, datas, temp_id)
# , result statuCode "000000"
if result.get("statusCode") == "000000":
# 0
return 0
else:
# -1
return -1
if __name__ == '__main__':
ccp = CCP()
# : 1
ccp.send_template_sms('15914397060', ['1234', 5], 1)
3.코드 구현1,백 엔 드 코드
views.py,이것 은 인증 코드 요청 을 받 는 처리 입 니 다.즉,백 엔 드 에 랜 덤 코드 를 만들어 핸드폰 사용자 에 게 보 낸 다음 에 랜 덤 코드 를 redis 에 저장 한 다음 에 전단 에 인증 코드 를 되 돌려 성공 적 인 신 호 를 보 냅 니 다.
from .models import User
from rest_framework import status
from lufei_drf.libs.yuntongxun.sms import CCP
from django_redis import get_redis_connection
class SMSCodeAPIView(APIView):
def get(self,request):
# 1.
phone = request.query_params.get("phone")
ty=request.query_params.get('type')
# 2.
if ty=='register':
try:
User.objects.get(phone=phone)
return Response({"message": " "}, status=status.HTTP_400_BAD_REQUEST)
except:
pass
redis = get_redis_connection("sms_code")
if redis.get("times_%s" % phone):
return Response({"message": " "}, status=status.HTTP_400_BAD_REQUEST)
# 3.
#
sms_code = "%04d" % random.randint(0, 9999)
ccp = CCP()
result = ccp.send_template_sms(phone,[sms_code,"5 "],1)
if result == 0:
# , redis
#
pl = redis.pipeline()
pl.multi() #
# setex( , [ ], )
SMS_EXPIRE_TIME = 5 * 60 #
SMS_TIMES = 60 #
#
pl.setex("sms_%s" % phone, SMS_EXPIRE_TIME, sms_code)
pl.setex("times_%s" % phone, SMS_TIMES, 1)
#
pl.execute()
# 4.
return Response({"message":result},status=status.HTTP_200_OK)
urls.py
from django.urls import path
# jwt
from rest_framework_jwt.views import obtain_jwt_token
from .views import SMSCodeAPIView,
urlpatterns=[
path(r"login/", obtain_jwt_token ),
path('sms/',SMSCodeAPIView.as_view()),
]
utils.py,이것 은 사용자 에 게 휴대 전화 인증 코드 를 제출 한 후 휴대 전화 번호 와 인증 코드 를 교정 하 는 것 입 니 다.판단 이 모두 정확 한 후에 token,user 정보 등 을 포함 한 대상 을 되 돌려 줍 니 다.
from django.contrib.auth.backends import ModelBackend
from django_redis import get_redis_connection
def jwt_response_payload_handler(token, user=None, request=None):
"""
jwt
:token jwt
:user [ ]
:request
"""
return {
'token': token,
'id': user.id,
'username': user.username,
}
#
import re
from .models import User#
def get_user_by_account(account):
"""
user
:param account: , ,
:return: User None
"""
try:
if re.match('^1[3-9]\d{9}$', account):
#
user = User.objects.get(phone=account)
else:
#
user = User.objects.get(username=account)
except User.DoesNotExist:
return None
else:
return user
# redis
def sms_code_verify(phone,sms_code):
redis = get_redis_connection("sms_code")
value=redis.get('sms_%s'%phone).decode()
if value==sms_code:
return True
return False
class UsernameMobileAuthBackend(ModelBackend):
"""
"""
def authenticate(self, request, username=None, password=None, **kwargs):
user = get_user_by_account(username) # 4 ,
if len(password)==4 and user is not None and sms_code_verify(username,password):
return user
elif user is not None and user.check_password(password):
return user
else:
return None
2,전단 코드login 구성 요소
<template>
<div id="login">
<div class="box">
<p>
<img src="../../assets/login_title.png" alt="">
</p>
<p class="sign"> !</p>
<div class="pass" v-show="num==1">
<div class="title2 cursor">
<span @click="num=1" :class="num==1 ? 'show' :''"> </span>
<span @click="num=2" :class="num==2 ? 'show' :''"> </span>
</div>
<input v-model="username" type="text" class="ss" placeholder=" / ">
<input v-model="password" type="password" class="ss" placeholder=" ">
<div id="captcha" class="ss"></div>
<div class="t1">
<div class="left">
<input type="checkbox" class="cursor" v-model="remenber">
<div class="remenber cursor" > </div>
</div>
<div class="right cursor"> </div>
</div>
<button class="login_btn" @click="login1"> </button>
<div class="register">
<span><router-link to="/register"> </router-link></span>
</div>
</div>
<div class="messge" v-show="num==2">
<div class="title2 cursor">
<span @click="num=1" :class="num==1 ? 'show' :''"> </span>
<span @click="num=2" :class="num==2 ? 'show' :''"> </span>
</div>
<input v-model="phone" type="text" class="ss" placeholder=" ">
<div class="sms">
<input v-model="sms_code" type="text" class="ss">
<div class="content" @click="get_sms_code">{{content}}</div>
</div>
<button class="login_btn" @click="sms_login"> </button>
<div class="register">
<span><router-link to="/register"> </router-link></span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name:'login',
data:function () {
return {
num:1,
username:'',
password:'',
remenber:'',
status:'',
content:' ',
phone:'',
sms_code:'',
}
},
methods:{
//
sms_login:function(){
let _this=this;
this.$axios.post('http://127.0.0.1:8000/user/login/',{
'username':_this.phone,
'password':_this.sms_code,
},{responseType:'json'})
.then(function (res) {
sessionStorage.token=res.data.token;
_this.$router.go(-1);
}).catch(function (error) {
console.log(error.response)
});
},
//
get_sms_code:function(){
let reg = /1[3-9]{2}\d{8}/;
if( reg.test(this.phone) ){
if(this.content == " "){
this.content=60;
let _this=this;
let tt=setInterval(function () {
if (_this.content>=1){
_this.content--
}
else {
_this.content=' ';
clearInterval(tt)
}
},1000);
this.$axios.get('http://127.0.0.1:8000/user/sms?type=login&phone='+this.phone)
.then(function (res) {
if(res.data.message==0){
alert(' ')
}
}).catch(function (error) {
console.log(error.response)
})
}
}else {
alert(' ')
}
},
//
login1:function () {
if (this.status==1){
let _this=this;
this.$axios.post('http://127.0.0.1:8000/user/login/',{
'username':_this.username,
'password':_this.password,
},{responseType:'json'})
.then(function (res) {
if (res.status==200){
if (_this.remenber){
sessionStorage.removeItem('token');
localStorage.token=res.data.token;
}
else {
localStorage.removeItem('token');
sessionStorage.token=res.data.token
}
_this.$router.go(-1);
}
else {
alert(' ')
}
})
.catch(function (error) {
alert(error.response.data.non_field_errors[0]);
console.log(error.response.data.non_field_errors);
});
}
else {
alert(' ')
}
},
handlerPopup:function (captchaObj) {
let _this=this;
captchaObj.onSuccess(function () {
var validate = captchaObj.getValidate();
_this.$axios.post("http://127.0.0.1:8000/user/yzm/",{
geetest_challenge: validate.geetest_challenge,
geetest_validate: validate.geetest_validate,
geetest_seccode: validate.geetest_seccode,
},{
responseType:"json",
}).then(function (res) {
_this.status=res.data.status
}).catch(function (error) {
console.log(error)
})
});
captchaObj.appendTo("#captcha");
}
},
created:function () {
let _this=this;
this.$axios.get("http://127.0.0.1:8000/user/yzm")
.then(function (res) {
let data=JSON.parse(res.data);
initGeetest({
width:'350px',
gt: data.gt,
challenge: data.challenge,
product: "popup",
offline: !data.success
}, _this.handlerPopup);
}).catch(function (error) {
console.log(error)
})
}
}
</script>
<style scoped>
#login{
background: url('../../assets/Login.jpg');
background-size: 100% 100%;
height: 100%;
position: fixed;
width: 100%;
}
.box{
width: 500px;
height: 600px;
margin: 0 auto;
margin-top: 200px;
text-align: center;
}
.box img{
width: 190px;
height: auto;
}
.box p{
margin: 0;
}
.sign{
font-size: 18px;
color: #fff;
letter-spacing: .29px;
padding-top: 10px;
padding-bottom: 50px;
}
.pass{
width: 400px;
height: 460px;
margin: 0 auto;
background-color: white;
border-radius: 4px;
}
.messge{
width: 400px;
height: 390px;
margin: 0 auto;
background-color: white;
border-radius: 4px;
}
.title2{
width: 350px;
font-size: 20px;
color: #9b9b9b;
padding-top: 50px;
border-bottom: 1px solid #e6e6e6;
margin: 0 auto;
margin-bottom: 20px;
}
.ss{
width: 350px;
height: 45px;
border-radius: 4px;
border: 1px solid #d9d9d9;
text-indent: 20px;
font-size: 14px;
margin-bottom: 20px;
}
.pass .t1{
width: 350px;
margin: 0 auto;
height: 20px;
line-height: 20px;
font-size: 12px;
text-align: center;
position: relative;
}
.t1 .right{
position: absolute;
right: 0;
}
.remenber{
display: inline-block;
position: absolute;
left: 20px;
}
.left input{
position: absolute;
left:0;
width: 14px;
height: 14px;
}
.login_btn{
width: 350px;
height: 45px;
background: #ffc210;
border-radius: 5px;
font-size: 16px;
color: #fff;
letter-spacing: .26px;
margin-top: 30px;
outline: none;
border:none;
cursor: pointer;
}
.register{
margin-top: 20px;
font-size: 14px;
color: #9b9b9b;
}
.register span{
color: #ffc210;
cursor: pointer;
}
.cursor{
cursor: pointer;
}
.show{
display: inline-block;
padding-bottom: 5px;
border-bottom: 2px solid orange;
color: #4a4a4a;
}
a{
text-decoration: none;
color: #ffc210;
}
#captcha{
margin: 0 auto;
height: 44px;
}
.sms{
position: relative;
width: 350px;
height: 45px;
margin: 0 auto;
line-height: 45px;
}
.sms .content{
position: absolute;
top:0;
right: 10px;
color: orange;
border-left: 1px solid orange;
padding-left: 10px;
cursor: pointer;
}
</style>
전단 에서 문자 인증 코드 가 져 오기:
//
get_sms_code:function(){
let reg = /1[3-9]{2}\d{8}/; // ,
if( reg.test(this.phone) ){ // ‘ ' , ; ,
if(this.content == " "){ // 60
this.content=60;
let _this=this;
let tt=setInterval(function () {
if (_this.content>=1){
_this.content--
}
else {
_this.content=' ';
clearInterval(tt)
}
},1000);
this.$axios.get('http://127.0.0.1:8000/user/sms?type=login&phone='+this.phone)
.then(function (res) {
if(res.data.message==0){
alert(' ')
}
}).catch(function (error) {
console.log(error.response)
})
}
}else {
alert(' ')
}
},
프론트 엔 드 는 핸드폰 번호 와 문자 인증 코드 로 로그 인 합 니 다.
//
get_sms_code:function(){
let reg = /1[3-9]{2}\d{8}/; // ,
if( reg.test(this.phone) ){ // ‘ ' , ; ,
if(this.content == " "){ // 60
this.content=60;
let _this=this;
let tt=setInterval(function () {
if (_this.content>=1){
_this.content--
}
else {
_this.content=' ';
clearInterval(tt)
}
},1000);
this.$axios.get('http://127.0.0.1:8000/user/sms?type=login&phone='+this.phone)
.then(function (res) {
if(res.data.message==0){
alert(' ')
}
}).catch(function (error) {
console.log(error.response)
})
}
}else {
alert(' ')
}
},
vuedrf 문자 인증 코드 를 실현 하 는 글 은 여기까지 입 니 다.vuedrf 문자 인증 코드 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Fastapi websocket 및 vue 3(Composition API)1부: FastAPI virtualenv 만들기(선택 사항) FastAPI 및 필요한 모든 것을 다음과 같이 설치하십시오. 생성main.py 파일 및 실행 - 브라우저에서 이 링크 열기http://127.0.0.1:...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.