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

作者:程序设计实验室 时间:2023-05-31 18:48:46 

前言

还是最近在做的一个小项目,后端用的是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 

来源:https://www.cnblogs.com/deali/p/16110129.html

标签:Django,前后端分离,登录
0
投稿

猜你喜欢

  • javascript在线游戏:找相同的图片

    2008-03-12 12:18:00
  • python Opencv实现停车位识别思路详解

    2023-10-20 21:54:25
  • CentOs7.x安装Mysql的详细教程

    2024-01-27 11:11:45
  • js修改原型的属性使用介绍

    2024-04-10 10:51:03
  • SQL Server中通过扩展存储过程实现数据库的远程备份与恢复

    2024-01-17 14:38:41
  • Python编写带选项的命令行程序方法

    2023-11-18 20:47:35
  • Python 避免字典和元组的多重嵌套问题

    2021-01-06 00:07:26
  • python实现比较两段文本不同之处的方法

    2021-01-29 17:53:43
  • ie的javascript失效问题

    2009-09-21 12:49:00
  • Python Web框架Flask中使用新浪SAE云存储实例

    2022-11-03 06:27:16
  • asp使用Application来统计在线人数方法

    2007-08-13 12:43:00
  • 关于python字符串方法分类详解

    2023-12-30 22:51:44
  • Django框架基础模板标签与filter使用方法详解

    2022-10-25 18:14:43
  • python3中宏HAVE_VFORK的使用

    2021-05-22 07:22:21
  • 剑走偏锋:体验ebay的AIR

    2008-11-13 11:51:00
  • 使用pytorch搭建AlexNet操作(微调预训练模型及手动搭建)

    2023-05-04 05:09:51
  • 通过 Django Pagination 实现简单分页功能

    2021-03-15 15:53:03
  • 用ajax实现的自动投票的代码

    2023-08-24 16:35:07
  • python实现两张图片拼接为一张图片并保存

    2023-01-26 17:56:52
  • python实现雨滴下落到地面效果

    2021-10-04 03:58:32
  • asp之家 网络编程 m.aspxhome.com