day78:luffy:前端对于token的认证&滑动验证码的实现
目录
1.前端对于token的认证
上文我们实现了对于前端能够通过token是否存在来判断用户是否登录,传送门: token对于登录状态的判断
对于token,不仅要判断token是否存在,而且要判断token是否有效

所以接下来我们做的事情:就是验证token是否真的有效
验证token是否有效
1.验证token有效需要引入verify_jwt_token
users/urls.py
from rest_framework_jwt.views import obtain_jwt_token, verify_jwt_token
from . import views
from django.urls import path urlpatterns = [ ......
path(r'verify/', verify_jwt_token), ]
2.在dev.py中可以设置token的过期时间
可以用来测试如果token过期是否还能登录
import datetime
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
}
3.drf测试
POST /users/login 输入用户名和密码,获取到token值
POST /users/verify 输入token值,获取到token值,用户名,id
4.改写check_login函数
改写之前写的check_login函数,由原来的判断token是否存在-->校验token
并且将check_login函数移动至setting.js作为公共函数 ,因为很多组件都需要用到这个功能
setting.js
// 实现思路:获取token值,并将token值POST提交到/users/verify进行验证
export default {
Host:"http://www.lyapi.com:8001",// server address
check_login(ths){
let token = localStorage.token || sessionStorage.token;
console.log('>>>>>',token);
ths.$axios.post(`${this.Host}/users/verify/`,{
token:token,
}).then((res)=>{
ths.token = token;
}).catch((error)=>{
ths.token = false;
})
}
}
Vheader.vue
// vheader组件执行一下方法
created(){
this.get_nav_data();
this.$settings.check_login(this); },
2.滑动验证码
1.滑动验证码实现的原理
前端的验证码时如何生成的

其实实际上是前端是需要后端来获取滑动验证码的

2.滑动验证码的代码实现
1.腾讯防水墙的appid和secret key放到dev.py配置文件中
dev.py
# 防水墙配置
FSQ = {
'appid':'2080330111',
'app_serect_key':'07v2KHaK2CMY8tkl_aOrbcA**',
}
2.web前端接入腾讯防水墙的js文件
index.html
<!-- index.html -->
<script src="https://ssl.captcha.qq.com/TCaptcha.js"></script>
3.点击登录按钮,触发登录按钮绑定的LoginHandle事件
// 通过这两行代码就可以实现点击登录按钮,出现滑动验证码图片了
var captcha1 = new TencentCaptcha('2080330111',function(res){});
captcha1.show(); // res:滑动成功或者失败的响应结果
console.log(res) // {appid:xxx,bizState:xxx,randstr:xxx,ret:0,ticket:xxx}
返回结果字段说明如下:
| 字段名 | 值类型 | 说明 |
|---|---|---|
| ret | Int | 验证结果,0:验证成功。2:用户主动关闭验证码。 |
| ticket | String | 验证成功的票据,当且仅当 ret = 0 时 ticket 有值。 |
| appid | String | 场景 ID。 |
| bizState | Any | 自定义透传参数。 |
| randstr | String | 本次验证的随机串,请求后台接口时需带上。 |
4.思考
当用户点击登录-->出现滑动验证码-->滑动成功-->给后台发请求,将用户名和密码发送到后端-->
用户名和密码发到后端了,是否代表着滑动验证就通过了吗?
并不是,所以验证码的数据也要在后台校验--->ticket值
5.检查验证码票据结果
如何验证滑动验证码是否滑动成功?

上图只是针对校验滑动验证码滑动是否成功
也可以同时校验 用户名 密码 滑动验证码数据

6.前端滑动验证码的代码实现
methods:{
loginHandle(){
var captcha1 = new TencentCaptcha('2080330111', (res) =>{
if (res.ret === 0){ // 滑动成功后才能够发post请求
this.$axios.post(`${this.$settings.Host}/users/login/`,{
username:this.username,
password:this.password,
// 将ticket和randstr也发送到后台去,让后台去验证滑动是否成功
ticket:res.ticket,
randstr:res.randstr,
}).then((res)=>{
console.log(res);
// 判断是临时登录还是永久登录
if (this.remember){
localStorage.token = res.data.token;
localStorage.username = res.data.username;
localStorage.id = res.data.id;
sessionStorage.removeItem('token');
sessionStorage.removeItem('username');
sessionStorage.removeItem('id');
}else {
sessionStorage.token = res.data.token;
sessionStorage.username = res.data.username;
sessionStorage.id = res.data.id;
localStorage.removeItem('token');
localStorage.removeItem('username');
localStorage.removeItem('id');
}
}).catch((error)=>{
this.$alert('用户名或者密码错误', '登录失败', {
confirmButtonText: '确定',
});
})
}
});
captcha1.show(); // 显示验证码
}
},
现在已经将数据发送给了后台,那么后台怎样进行校验呢?
昨天我们使用的obtain_jwt_token:只能做用户名和密码的验证,无法实现对滑动成功的验证,
所以我们需要改写代码添加字段,让jwt也能够实现对滑动成功的验证
7.重写jwt代码来实现对滑动成功的认证
users/urls.py
# users/urls.py from rest_framework_jwt.views import verify_jwt_token
from . import views
from django.urls import path urlpatterns = [
# 因为我们要改写jwt了,所以不能继承原来的obtain_jwt_token了
# 我们要自己改写这部分的视图函数来实现对于滑动成功的认证
path(r'login/', views.CustomLoginView.as_view()),
path(r'verify/', verify_jwt_token), ]
users/views.py
# users/views.py from django.shortcuts import render from rest_framework_jwt.views import ObtainJSONWebToken from lyapi.apps.users.serializers import CustomeSerializer class CustomLoginView(ObtainJSONWebToken):
serializer_class = CustomeSerializer
users/serializers.py
# users/serializers.py from rest_framework_jwt.serializers import JSONWebTokenSerializer
from rest_framework import serializers
from rest_framework_jwt.compat import get_username_field, PasswordField
from django.utils.translation import ugettext as _
from django.contrib.auth import authenticate, get_user_model
from rest_framework_jwt.settings import api_settings
User = get_user_model()
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
jwt_get_username_from_payload = api_settings.JWT_PAYLOAD_GET_USERNAME_HANDLER class CustomeSerializer(JSONWebTokenSerializer): def __init__(self, *args, **kwargs):
"""
Dynamically add the USERNAME_FIELD to self.fields.
"""
super(JSONWebTokenSerializer, self).__init__(*args, **kwargs) # 重写jwt自带的序列化器,在原来的基础上添加ticket和randstr
self.fields[self.username_field] = serializers.CharField()
self.fields['password'] = PasswordField(write_only=True)
self.fields['ticket'] = serializers.CharField(write_only=True)
self.fields['randstr'] = serializers.CharField(write_only=True) # 全局钩子函数
def validate(self, attrs):
credentials = {
self.username_field: attrs.get(self.username_field),
'password': attrs.get('password'),
'ticket': attrs.get('ticket'),
'randstr': attrs.get('randstr'),
} if all(credentials.values()): user = authenticate(self.context['request'],**credentials) # self.context['request']当前请求的request对象 if user:
if not user.is_active:
msg = _('User account is disabled.')
raise serializers.ValidationError(msg) payload = jwt_payload_handler(user) return {
'token': jwt_encode_handler(payload),
'user': user
}
else:
msg = _('Unable to log in with provided credentials.')
raise serializers.ValidationError(msg)
else:
msg = _('Must include "{username_field}" and "password".')
msg = msg.format(username_field=self.username_field)
raise serializers.ValidationError(msg)
users/utils.py
# users/utils.py class CustomeModelBackend(ModelBackend):
'''
'
'ticket': attrs.get('ticket'),
'randstr': attrs.get('randstr'), '''
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user_obj = get_user_obj(username)
ticket = kwargs.get('ticket')
userip = request.META['REMOTE_ADDR']
randstr = kwargs.get('randstr') params = { # 腾讯防水墙需要的一些参数
"aid": settings.FSQ.get('appid'),
"AppSecretKey": settings.FSQ.get('app_serect_key'),
"Ticket": ticket,
"Randstr": randstr,
"UserIP": userip
} params = urlencode(params).encode() # 转换成bytes类型
url = settings.FSQ.get('URL') f = urlopen(url, params) # 发送请求,将数据发送出去,并返回滑动是否成功数据 content = f.read() # 获取数据
res = json.loads(content) # json反序列化
print(res) # {'response': '1', 'evil_level': '0', 'err_msg': 'OK'} if res.get('response') != '1': # 如果滑动失败
return None if user_obj: # 如果用户名存在
if user_obj.check_password(password): # 如果密码正确
return user_obj # 返回用户名对象 else: # 如果用户名或密码错误
return None
except Exception:
logger.error('验证过程代码有误,请联系管理员')
return None
day78:luffy:前端对于token的认证&滑动验证码的实现的更多相关文章
- django基于存储在前端的token用户认证
一.前提 首先是这个代码基于前后端分离的API,我们用了django的framework模块,帮助我们快速的编写restful规则的接口 前端token原理: 把(token=加密后的字符串,key= ...
- 使用 AngularJS & NodeJS 实现基于token 的认证应用(转)
认证是任何 web 应用中不可或缺的一部分.在这个教程中,我们会讨论基于 token 的认证系统以及它和传统的登录系统的不同.这篇教程的末尾,你会看到一个使用 AngularJS 和 NodeJS 构 ...
- 使用 AngularJS & NodeJS 实现基于 token 的认证应用
认证是任何Web应用中不可或缺的一部分.在这个教程中,我们会讨论基于token的认证系统以及它和传统的登录系统的不同.这篇教程的末尾,你会看到一个使用 AngularJS 和 NodeJS 构建的 ...
- NodeJS 实现基于 token 的认证应用
此段摘自 http://zhuanlan.zhihu.com/FrontendMagazine/19920223 英文原文 http://code.tutsplus.com/tutorials/tok ...
- 记一次token安全认证的实践
阅读此文前请先阅读上一篇SpringBoot整合JWT实现用户认证了解JWT. 背景介绍: 因项目需求,有PC端 APP端和小程序端,但登陆接口是同一个,然而微服务也无法使用传统的session解决用 ...
- 理解JWT(JSON Web Token)认证
理解JWT(JSON Web Token)认证 最近想做个小程序,需要用到授权认证流程.以前项目都是用的 OAuth2 认证,但是Sanic 使用OAuth2 不太方便,就想试一下 JWT 的认证方式 ...
- vue中前端处理token过期的方法与axios请求拦截处理
在处理token过期的这个问题上困扰了我很久,现在终于解决的了,所以分享出来给大家,希望能够对大家有所帮助. 首先,当然是路由进行拦截,路由拦截当然是在beforeEach中了: router.bef ...
- ASP.NET WebApi 基于OAuth2.0实现Token签名认证
一.课程介绍 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将是我们需要思考的问题.为了保护我们的WebApi数 ...
- ASP.NET WebApi 基于JWT实现Token签名认证
一.前言 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebServi ...
随机推荐
- Mac 系统下如何显示和隐藏文件
苹果Mac OS X操作系统下,隐藏文件是否显示有很多种设置方法,最简单的要算在Mac终端输入命令.显示/隐藏Mac隐藏文件命令如下(注意其中的空格并且区分大小写): 第一种方式: 显示Mac隐藏文件 ...
- 高德AR & 车道级导航技术演进与实践
2020云栖大会于9月17日-18日在线上举行,阿里巴巴高德地图携手合作伙伴精心组织了"智慧出行"专场,为大家分享高德地图在打造基于DT+AI和全面上云架构下的新一代出行生活服务平 ...
- Java集合-07Map接口及其抽象类
简介 前面把List基本记录完了,对于集合List,Map,Set,因为Set基于Map,故先记录Map. 这一篇主要记录Map接口及其抽象类(java version:1.8) 整体架构 参考上图, ...
- Python-维护排序好的序列模块-bisect
bisect模块 处理已经排序的序列,升序,从小到大,分插入数据和查看插入数据的位置两大核心,类似于插入排序算法 插入数据 # 首先这个序列按升序规则已经排序好的 # 查找规则是二分查找,当数据相等的 ...
- Pots(POJ - 3414)【BFS 寻找最短路+路径输出】
Pots(POJ - 3414) 题目链接 算法 BFS 1.这道题问的是给你两个体积分别为A和B的容器,你对它们有三种操作,一种是装满其中一个瓶子,另一种是把其中一个瓶子的水都倒掉,还有一种就是把其 ...
- Python3基础——递归
递归函数 如果一个函数在内部调用自身本身,这个函数就是递归函数. 递归函数的优点是定义简单,逻辑清晰.理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰. 使用递归函数需要注意防止栈 ...
- Arduino PID Library
Arduino PID Library by Brett Beauregard,contact: br3ttb@gmail.com What Is PID? PID是什么 From Wikipe ...
- Java 生态碎片化 和 .NET生态的一致性
.NET Core是以MIT协议开源, Java是GPL协议开源.Java 8 SDK升级Oracle要收费这件事对于很多小公司是有着重大的影响的,Java生态越发碎片化,有众多的OpenJDK发行版 ...
- AD(Altium Designer)PCB布线中的“格式刷”,助力快速布局布线
摘要:在AD(Altium Designer)进行电路板布线时,孔丙火(微信公众号:孔丙火)经常会碰到电路中有相同功能的模块,比如2路相同的RS485通信电路.多路相同继电器输出电路.多路相同的输入电 ...
- Centos7系统下Docker开启认证的远程端口2376配置教程
docker开启2375会存在安全漏洞 暴露了2375端口的Docker主机.因为没有任何加密和认证过程,知道了主机IP以后,,任何人都可以管理这台主机上的容器和镜像,以前贪图方便,只开启了没有认证的 ...