加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

day78:luffy:前端对于token的认证&滑动验证码的实现

发布时间:2020-12-20 09:58:29 所属栏目:Python 来源:网络整理
导读:目录 1.前端对于token的认证 2.滑动验证码 1.滑动验证码实现的原理 2.滑动验证码的代码实现 1.配置文件 2.前端实现:Login.vue 3.后端实现:改写jwt代码 1.前端对于token的认证 上文我们实现了对于前端能够通过token是否存在来判断用户是否登录,传送门:?token

目录

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 .  views
from django.urls  path

urlpatterns = [

    ......
    path(r'verify/',verify_jwt_token),]

2.在dev.py中可以设置token的过期时间

可以用来测试如果token过期是否还能登录

 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('>>>>>'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();

  },

2.滑动验证码

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

前端的验证码时如何生成的

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

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

1.腾讯防水墙的appid和secret key放到dev.py配置文件中

dev.py

# 防水墙配置
FSQ =appid':2080330111app_serect_key07v2KHaK2CMY8tkl_aOrbcA**index.html

<!-- index.html -->
<script src="https://ssl.captcha.qq.com/TCaptcha.js"></script>

3.点击登录按钮,触发登录按钮绑定的LoginHandle事件

 通过这两行代码就可以实现点击登录按钮,出现滑动验证码图片了
var captcha1 = new TencentCaptcha('2080330111',1)">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(){
      {
        if (res.ret === 0){  滑动成功后才能够发post请求

          this.$axios.post(`${this.$settings.Host}/users/login/`,{
            username:.username,password:.password, 将ticket和randstr也发送到后台去,让后台去验证滑动是否成功
            ticket:res.ticket,randstr:res.randstr,1)">{
            console.log(res);
              
             判断是临时登录还是永久登录
            if (.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');
            }
              
          }).{
            this.$alert('用户名或者密码错误','登录失败' 显示验证码



    }

  },

现在已经将数据发送给了后台,那么后台怎样进行校验呢?

昨天我们使用的obtain_jwt_token:只能做用户名和密码的验证,无法实现对滑动成功的验证

所以我们需要改写代码添加字段,让jwt也能够实现对滑动成功的验证

7.重写jwt代码来实现对滑动成功的认证

users/urls.py verify_jwt_token [
因为我们要改写jwt了,所以不能继承原来的obtain_jwt_token了 我们要自己改写这部分的视图函数来实现对于滑动成功的认证 path(rlogin/

users/views.py

 users/views.py

from django.shortcuts  render

 ObtainJSONWebToken

from lyapi.apps.users.serializers  CustomeSerializer


class CustomLoginView(ObtainJSONWebToken):
    serializer_class = CustomeSerializer

users/serializers.py

 users/serializers.py


from rest_framework_jwt.serializers  JSONWebTokenSerializer
from rest_framework  serializers
from rest_framework_jwt.compat  get_username_field,PasswordField
from django.utils.translation  ugettext as _
from django.contrib.auth  authenticate,get_user_model
from rest_framework_jwt.settings  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

 CustomeSerializer(JSONWebTokenSerializer):

    def __init__(self,*args,**kwargs):
        """
        Dynamically add the USERNAME_FIELD to self.fields.
        """
        super(JSONWebTokenSerializer,self).__init__(*args,1)">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=randstrTrue)

     全局钩子函数
    def validate(self,attrs):
        credentials = {
            self.username_field: attrs.get(self.username_field),1)">': attrs.get(if all(credentials.values()):

            user = authenticate(self.context[request'],**credentials)   self.context['request']当前请求的request对象

             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),1)">user: user
                }
            :
                msg = _(Unable to log in with provided credentials.)
                 serializers.ValidationError(msg)
        :
            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

 CustomeModelBackend(ModelBackend):
    '''
        '
        'ticket': attrs.get('ticket'),'randstr': attrs.get('randstr'),1)">'''
    def authenticate(self,request,username=None,password=None,1)">kwargs):
        try:
            user_obj = get_user_obj(username)
            ticket = kwargs.get()
            userip = request.META[REMOTE_ADDR]
            randstr = kwargs.get()
          
            params = {  腾讯防水墙需要的一些参数
                "aid": settings.FSQ.get(AppSecretKeyTicket": ticket,1)">Randstr: randstr,1)">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':  如果滑动失败
                 None

            if user_obj:  如果用户名存在
                if user_obj.check_password(password):  如果密码正确
                    return user_obj  返回用户名对象

            else:  如果用户名或密码错误
                 None
        except Exception:
            logger.error(验证过程代码有误,请联系管理员)
            return None

?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读