目录

1.前端对于token的认证

2.滑动验证码

  1.滑动验证码实现的原理

  2.滑动验证码的代码实现

    1.配置文件

    2.前端实现:Login.vue

    3.后端实现:改写jwt代码

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的认证&滑动验证码的实现的更多相关文章

  1. django基于存储在前端的token用户认证

    一.前提 首先是这个代码基于前后端分离的API,我们用了django的framework模块,帮助我们快速的编写restful规则的接口 前端token原理: 把(token=加密后的字符串,key= ...

  2. 使用 AngularJS & NodeJS 实现基于token 的认证应用(转)

    认证是任何 web 应用中不可或缺的一部分.在这个教程中,我们会讨论基于 token 的认证系统以及它和传统的登录系统的不同.这篇教程的末尾,你会看到一个使用 AngularJS 和 NodeJS 构 ...

  3. 使用 AngularJS & NodeJS 实现基于 token 的认证应用

      认证是任何Web应用中不可或缺的一部分.在这个教程中,我们会讨论基于token的认证系统以及它和传统的登录系统的不同.这篇教程的末尾,你会看到一个使用 AngularJS 和 NodeJS 构建的 ...

  4. NodeJS 实现基于 token 的认证应用

    此段摘自 http://zhuanlan.zhihu.com/FrontendMagazine/19920223 英文原文 http://code.tutsplus.com/tutorials/tok ...

  5. 记一次token安全认证的实践

    阅读此文前请先阅读上一篇SpringBoot整合JWT实现用户认证了解JWT. 背景介绍: 因项目需求,有PC端 APP端和小程序端,但登陆接口是同一个,然而微服务也无法使用传统的session解决用 ...

  6. 理解JWT(JSON Web Token)认证

    理解JWT(JSON Web Token)认证 最近想做个小程序,需要用到授权认证流程.以前项目都是用的 OAuth2 认证,但是Sanic 使用OAuth2 不太方便,就想试一下 JWT 的认证方式 ...

  7. vue中前端处理token过期的方法与axios请求拦截处理

    在处理token过期的这个问题上困扰了我很久,现在终于解决的了,所以分享出来给大家,希望能够对大家有所帮助. 首先,当然是路由进行拦截,路由拦截当然是在beforeEach中了: router.bef ...

  8. ASP.NET WebApi 基于OAuth2.0实现Token签名认证

    一.课程介绍 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将是我们需要思考的问题.为了保护我们的WebApi数 ...

  9. ASP.NET WebApi 基于JWT实现Token签名认证

    一.前言 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebServi ...

随机推荐

  1. C语言专项错题集

    2020-08-10 记录 #1 1 struct student{ 2 int num; 3 int age; 4 }; 5 struct student stu[3]={{6001,20},{60 ...

  2. spring注解(Component、依赖注入、生命周期、作用域)

    1.注解 注解就是一个类,使用@加上注解名称,开发中可以使用注解取代配置文件 2.@Component 取代<bean  class="">,@Component 取代 ...

  3. JavaEE的核心API与组件

    JAVAEE Java ee 平台由一整套服务(Services).应用程序接口(APIs)和协议构成,它对开发基于Web的多层应用提供了功能支持,下面对JAVAEE中的13种技术规范进行简单的描述( ...

  4. lamda表达式与Stream 流操作,reduce,flatMap,groupingBy等

    /** * 符合lambda表达式的接口也叫函数式接口: * 除了默认方法和Object类的方法外,只有一个抽象方法的接口才能符合lambda表达式的要求 * 可以使用@FunctionalInter ...

  5. 升​级​到​w​i​n​8​.​1​导​致​o​r​a​c​l​e​服​务​丢​失​的​处​理

    针对升级到win8.1导致oracle服务丢失的处理 1.首先保证oracle相关程序能够运行,如net manager,如果能够运行,说明oracle安装仍然有效,只是因为服务被"净化&q ...

  6. HTML中限制input 输入框输入内容

    限制 input 输入框只能输入纯数字1.onkeyup = "value=value.replace(/[^\d]/g,'')" 使用 onkeyup 事件,有 bug ,那就是 ...

  7. 008 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 02 Java 中的关键字

    008 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 02 Java 中的关键字 关键字 关键字就是一些有特殊意义的词 之前学习的程序中涉及到的关键字 Java中 ...

  8. 《穷查理年鉴》贪嗔痴 & 懒贪装(关于败坏)

    贪嗔痴 & 懒贪装 1)伤害 041.仇恨加重伤害,漠视消除伤害. 042.90%的伤害是自己造成的. 044.伤害你的敌人使你比他更低下;仇恨使你和他一样;宽恕才能让你超越他. 109.让仇 ...

  9. Oracle 数据库导入数据和编码问题

    配置 control 文件: load data characterset utf8 append into table role_res_gold fields terminated by ';' ...

  10. 自定义Antd Pro 默认元素

    概要 通用元素 修改的方式 主页面 标签上的图标 logo 和 系统名称 footer 的配置 loading 页面 最终效果 概要 使用 Antd Pro 来开发前端项目时, 生成的项目模板中, 一 ...