微信小程序-drf登录认证组件

微信小程序-drf登录认证组件

- 通过全局的用户判断是否登录- 登录用户则校验用户的token值

1. config - settings.js

 - api.js - settings.js# 模块化:登录页面路由module.exports = { loginPage: "/pages/login/login"}

2. utils - auth.js

 - auth.js# 获取应用实例var settings = require('../config/settings.js')var app = getApp()function authentication() { if (!app.globalData.userInfo) { wx.navigateTo({ // settings.loginPage,登录路由 url: settings.loginPage }) return false } return true}# 认证函数模块化module.exports = { authentication: authentication}

3. 示例:用户评论

pages - newsDetail - newsDetail.js // pages/newsDetail/newsDetail.jsvar api = require("../../config/api.js")var auth = require('../../utils/auth.js')var app = getApp()# 评论之前判断用户是否登录onClickShowCommentModal: function(e) { if (!auth.authentication()) { return } var replyInfo = e.currentTarget.dataset; this.setData({ isShowCommentModal: true, reply: replyInfo, });},

4. 提交评论-- 用户已登录,发送请求携带token值

'''# 请求头携带用户的token值,此处涉及到js的三元运算header: { Authorization: userInfo ? "token " + userInfo.token : "" },'''onClickPostComment: function() {// 发布评论,将评论数据发送到后台接口var userInfo = app.globalData.userInfo;wx.request({ url: api.Comment, data: this.data.reply, method: 'POST', dataType: 'json', header: { Authorization: userInfo ? "token " + userInfo.token : "" }, responseType: 'text', success: (res) => { ... } }) }

5. 后端校验 token值是否一致

utils - auth.py'''如果用户已登录,则在request.user和request.auth中赋值;未登录则做任何操作。用户需要在请求头Authorization中传递token,格式如下: Authorization: token 401f7ac837da42b97f613d789819ff93537bee6a建议:配合和配置文件一起使用,未认证的用户request.user和request.auth的值为NoneREST_FRAMEWORK = { "UNAUTHENTICATED_USER":None, "UNAUTHENTICATED_TOKEN":None}'''

通用认证

#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.authentication import BaseAuthenticationfrom rest_framework.authentication import get_authorization_headerfrom apps.api import modelsfrom rest_framework import exceptionsclass GeneralAuthentication(BaseAuthentication): """ 通用认证(所有页面都可以应用) """ keyword = "token" def authenticate(self, request): # 认证元组 auth_tuple = get_authorization_header(request).split() # 1.如果没有传token,则通过本次认证,进行之后的认证 if not auth_tuple: return None # 2.如果传递token,格式不符,则通过本次认证,进行之后的认证 if len(auth_tuple) != 2: return None # 3.如果传递了token,但token的名称不符,则通过本次认证,进行之后的认证 if auth_tuple[0].lower() != self.keyword.lower().encode(): return None # 4.对token进行认证,如果通过了则给request.user和request.auth赋值,否则返回None try: token = auth_tuple[1].decode() user_object = models.UserInfo.objects.get(token=token) return (user_object, token) except Exception as e: return None

用户认证

class UserAuthentication(BaseAuthentication): """ token 认证 """ keyword = "token" def authenticate(self, request): auth_tuple = get_authorization_header(request).split() ''' print(auth_tuple) auth_tuple = [b'token', b'a33409078e8ff69c16e813442ac1ce5d'] ''' if not auth_tuple: raise exceptions.AuthenticationFailed('认证失败') if len(auth_tuple) != 2: raise exceptions.AuthenticationFailed('认证失败') if auth_tuple[0].lower() != self.keyword.lower().encode(): raise exceptions.AuthenticationFailed('认证失败') try: token = auth_tuple[1].decode() user_object = models.UserInfo.objects.get(token=token) return (user_object, token) except Exception as e: raise exceptions.AuthenticationFailed('认证失败')

视图函数添加认证类 --评论

from utils.auth import UserAuthentication, GeneralAuthenticationclass CommentView(CreateAPIView, ListAPIView): ''' POST请求提交评论:用户认证类 ''' serializer_class = CommentModelSerializer queryset = models.CommentRecord.objects filter_backends = [ChildCommentFilter, ] def get_authenticators(self): if self.request.method == 'POST': return [UserAuthentication(), ] return [GeneralAuthentication(), ]

相关文章