Django + Taro 前后端分离项目实现企业微信登录功能


Posted in Python onApril 07, 2022

前言

还是最近在做的一个小项目,后端用的是Django搭配RestFramework做接口,前端第一次尝试用京东开源的Taro框架来做多端(目前需要做用于企业微信的H5端和微信小程序)

本文记录一下企业微信登录的流程,上周看文档看得头晕晕的,其实很简单,封装好了就几行代码的事~

两种方式

  • 一种是先拼接好登录要用的地址authorize_url,回调地址设置成h5应用的网页入口,然后把authorize_url设置为企业微信里的应用主页就行,然后直接提取链接里的code
  • 另一种是在应用里拼接authorize_url地址,回调地址同样设置成h5应用的网页入口,然后应用里去请求authorize_url,然后提取链接里的code用来登录就行

说是两种,其实流程都是一样的,只不过第一种少去了前端拼接authorize_url以及首次请求的操作,为了方便起见,本文推荐使用第一种

思路

假设前端地址是http://xxx.com,那么我们用后端生成的企业微信登录地址中会把前端地址作为回调地址传入,在企业微信中访问登录地址之后,回跳转到我们的前端地址,并在路径中附上参数code,形式如下:

http://xxx.com?code=dkwawen123j13bk1

所以前端要做的就是拿到这串code,并提交给后端,让后端拿code去微信服务器换用户信息,就这样~

后端代码

企业微信登录的接口已经集成在我的「DjangoStarter」项目模板中,可以直接食用~

后端使用的是wechatpy这个库,非常好用,封装了微信开发的常用功能~

下面写一下两个关键的方法

from django.conf import settings
from django.contrib.auth import login
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token
from drf_yasg2.utils import swagger_auto_schema
from drf_yasg2 import openapi
from rest_framework.exceptions import APIException
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.request import HttpRequest
from rest_framework.decorators import action
from wechatpy.enterprise import WeChatClient
from apps.core.serializers import UserSerializer
class WechatWork(viewsets.ViewSet):
    """微信企业号相关认证服务"""
    client = WeChatClient(
        settings.WECHAT_WORK_CONFIG['CORP_ID'],
        settings.WECHAT_WORK_CONFIG['SECRET'],
    )
    @swagger_auto_schema(operation_summary='获取微信企业号登录链接')
    @action(detail=False)
    def get_authorize_url(self, request):
        return Response({
            # todo 这里要写上前端应用入口地址
            'url': self.client.oauth.authorize_url('http://xxx.com')
        })
    @swagger_auto_schema(
        operation_summary='通过code登录',
        manual_parameters=[
            openapi.Parameter(
                name='code', in_=openapi.IN_QUERY,
                description='从微信企业号服务器获取到的code',
                type=openapi.TYPE_STRING)
        ])
    @action(detail=False, methods=['POST'])
    def login_by_code(self, request: HttpRequest):
        code = request.GET.get('code', None)
        try:
            user_info = self.client.oauth.get_user_info(code)
        except Exception as e:
            raise APIException(detail=e)
        phone = user_info['UserId']
        is_created_user = False
        if User.objects.filter(username=phone).exists():
            user_obj: User = User.objects.get(username=phone)
        else:
            is_created_user = True
            user_obj: User = User.objects.create_user(username=phone, password=phone)
        # 记录Django登录状态
        login(request, user_obj)
        # 生成drf token
        token, created = Token.objects.get_or_create(user=user_obj)
            'user': UserSerializer(user_obj).data,
            'user_info': user_info,
            'successful': True,
            'is_created_user': is_created_user,
            'token': token.key,
            'message': '企业微信登录成功',

写完接口配置一下路由(这里就不重复了)

然后请求这个get_authorize_url接口,得到一个地址

{
  "message": "请求成功",
  "code": 200,
  "data": {
    "url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx386...&redirect_uri=http%3A%2F%2Fxxx.com&response_type=code&scope=snsapi_base#wechat_redirect"
  }
}

比如我上面写的应用入口地址是http://xxx.com,那么得到的企业微信登录地址就是

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx386...&redirect_uri=http%3A%2F%2Fxxx.com&response_type=code&scope=snsapi_base#wechat_redirect

各个参数的意义看企业微信官方文档就行,我们不用细究

企业微信应用配置

接下来我们把这个地址设置成企业微信应用的主页

如图

Django + Taro 前后端分离项目实现企业微信登录功能

同时还得设置一下「可信域名」,在同个页面的最下方「开发者接口」处,把前端应用部署所在的服务器域名和端口(80就不用)填上去就行~

这样应用配置就好了

前端代码

前端用的是京东开源的Taro框架,我前一篇文章写到我终于用上了React,说的就是在Taro开发里用React+TypeScript,开发体验非常好 (除了这个框架有一些让人无语的坑之外)

前端要实现的就是从路径参数里取出code

我们看到,Taro官方文档就有关于路由参数的处理

所以可以这样写来获取code(函数式组件写法)

import { getCurrentInstance } from '@tarojs/taro'
let code getCurrentInstance().router?.params['code']

然而!这样在普通页面跳转是可以的

比如这种形式

http://xxx.com/#/pages/index/index?code=abc

但人家微信登录回调跳转的地址形式是这样

http://xxx.com?code=abc&state=#/pages/index/index

这根本就拿不到code啊 o(´^`)o

所以得自己用js封装一个

直接上代码了

// 解析微信redirect_uri地址中的code
export const getCodeFromUrl = (url: string) => {
  let code = ''
  let index = url.indexOf('?')
  let paramStr = url.substring(index + 1, url.length);
  let params = paramStr.split('&')
  params.forEach(element => {
    if (element.indexOf('code') >= 0) {
      code = element.substring(element.indexOf('=') + 1, element.length)
    }
  });
  return code
}

使用的时候

let code = getCodeFromUrl(window.location.href)

就可以拿到code了

code都有了,后面就不用多说了~

参考资料

wechatpy库文档:http://docs.wechatpy.org/zh_CN/stable/oauth.html

企业微信文档:https://developer.work.weixin.qq.com/document/path/91335

Taro框架文档:https://taro-docs.jd.com/taro/docs/router 

到此这篇关于Django + Taro 前后端分离项目实现企业微信登录 功能的文章就介绍到这了,更多相关Django前后端分离登录内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python pycurl验证basic和digest认证的方法
May 02 Python
Python基于pyCUDA实现GPU加速并行计算功能入门教程
Jun 19 Python
python logging重复记录日志问题的解决方法
Jul 12 Python
详解Python with/as使用说明
Dec 13 Python
在Python中表示一个对象的方法
Jun 25 Python
Python3多线程版TCP端口扫描器
Aug 31 Python
Python从文件中读取指定的行以及在文件指定位置写入
Sep 06 Python
Python 类方法和实例方法(@classmethod),静态方法(@staticmethod)原理与用法分析
Sep 20 Python
Python numpy线性代数用法实例解析
Nov 15 Python
python实点云分割k-means(sklearn)详解
May 28 Python
如何在Python对Excel进行读取
Jun 04 Python
撤回我也能看到!教你用Python制作微信防撤回脚本
Jun 11 Python
Python OpenCV实现图像模板匹配详解
Python实现日志实时监测的示例详解
Python使用PyYAML库读写yaml文件的方法
Apr 06 #Python
python+pytest接口自动化之token关联登录的实现
Python图像处理库PIL详细使用说明
Apr 06 #Python
Python可变与不可变数据和深拷贝与浅拷贝
Apr 06 #Python
Python 全局空间和局部空间
Apr 06 #Python
You might like
PHP Squid中可缓存的动态网页设计
2008/09/17 PHP
在Windows系统下使用PHP生成Word文档的教程
2015/07/03 PHP
thinkPHP2.1自定义标签库的导入方法详解
2016/07/20 PHP
PHPCMS V9 添加二级导航的思路详解
2016/10/20 PHP
JS函数验证总结(方便js客户端输入验证)
2010/10/29 Javascript
js分解url参数(面向对象-极简主义法应用)
2012/08/09 Javascript
javascript学习(二)javascript常见问题总结
2013/01/02 Javascript
JS实现图片横向滚动效果示例代码
2013/09/04 Javascript
jQuery前端框架easyui使用Dialog时bug处理
2014/12/05 Javascript
jQuery处理XML文件的几种方法
2016/06/14 Javascript
JavaScript仿网易选项卡制作代码
2016/10/06 Javascript
详解jQuery简单的表单应用
2016/12/16 Javascript
js实现五星评价功能
2017/03/08 Javascript
详解webpack自动生成html页面
2017/06/29 Javascript
webpack打包js文件及部署的实现方法
2017/12/18 Javascript
AngularJS对动态增加的DOM实现ng-keyup事件示例
2018/03/12 Javascript
JS的函数调用栈stack size的计算方法
2018/06/24 Javascript
微信小程序下拉框组件使用方法详解
2018/12/28 Javascript
Vue formData实现图片上传
2019/08/20 Javascript
vue实现导航标题栏随页面滚动渐隐渐显效果
2020/03/12 Javascript
JavaScript arguments.callee作用及替换方案详解
2020/09/02 Javascript
Js数组扁平化实现方法代码总汇
2020/11/11 Javascript
python实现的jpg格式图片修复代码
2015/04/21 Python
Python判断变量是否为Json格式的字符串示例
2017/05/03 Python
Python实现简单网页图片抓取完整代码实例
2017/12/15 Python
Python学习笔记之open()函数打开文件路径报错问题
2018/04/28 Python
Python实现查找二叉搜索树第k大的节点功能示例
2019/01/24 Python
Python跳出多重循环的方法示例
2019/07/03 Python
如何真正的了解python装饰器
2020/08/14 Python
北美最大的参茸药食商城:德成行
2020/12/06 全球购物
简历的个人自我评价范文
2014/01/03 职场文书
咖啡厅创业计划书范本
2014/01/22 职场文书
《蚕姑娘》教学反思
2014/04/15 职场文书
搞笑爱情保证书
2014/04/29 职场文书
秋季运动会广播稿(30篇)
2014/09/13 职场文书
8个JS的reduce使用实例和reduce操作方式
2021/10/05 Javascript