day78:luffy:前端对于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_tokenusers/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),] 可以用来测试如果token过期是否还能登录 datetime JWT_AUTH = { JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),} 3.drf测试
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
? ? ? ? ? ? ? ? 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
[ 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 ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |