前言

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

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

企业微信应用配置

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

如图

同时还得设置一下「可信域名」,在同个页面的最下方「开发者接口」处,把前端应用部署所在的服务器域名和端口(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都有了,后面就不用多说了~

参考资料

Django + Taro 前后端分离项目实现企业微信登录的更多相关文章

  1. nginx+vue+uwsgi+django的前后端分离项目部署

    Vue+Django前后端分离项目部署,nginx默认端口80,数据提交监听端口9000,反向代理(uwsgi配置)端口9999 1.下载项目文件(统一在/opt/luffyproject目录) (1 ...

  2. 前后端分离项目shiro的未登录和权限不足

    在前后端分离的项目中.前端代码和后端代码几乎不在同一个目录下,甚至不是在一台服务器上:我这个项目部署在linux.同一台服务器,不同目录下:所有的页面跳转由前台路由,后台只是提供返回的数据: 干货↓  ...

  3. uwsgi加nginx部署django restframework前后端分离项目

    一.uwsgi和nginx简介 1.uwsgi(摘抄于百度百科): uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与 ...

  4. Django+Vue前后端分离项目的部署

    部署静态文件: 静态文件有两种方式 1:通过django路由访问 2:通过nginx直接访问 方式1: 需要在根目录的URL文件中增加 url(r'^$', TemplateView.as_view( ...

  5. 【转】python+django+vue搭建前后端分离项目

    https://www.cnblogs.com/zhixi/p/9996832.html 以前一直是做基于PHP或JAVA的前后端分离开发,最近跟着python风搭建了一个基于django的前后端分享 ...

  6. python+django+vue搭建前后端分离项目

    以前一直是做基于PHP或JAVA的前后端分离开发,最近跟着python风搭建了一个基于django的前后端分享项目 准备工作:IDE,[JetBrains PyCharm2018][webpack 3 ...

  7. Win10环境前后端分离项目基于Vue.js+Django+Python3实现微信(wechat)扫码支付流程(2021年最新攻略)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_182 之前的一篇文章:mpvue1.0+python3.7+Django2.0.4实现微信小程序的支付功能,主要介绍了微信小程序内 ...

  8. 海纳百川无所不容,Win10环境下使用Docker容器式部署前后端分离项目Django+Vue.js

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_179 随着现代化产品研发的不断推进,我们会发现,几乎每个产品线都会包含功能各异的服务,而且服务与服务之间存在也会存在着错综复杂的依 ...

  9. 解决Django+Vue前后端分离的跨域问题及关闭csrf验证

      前后端分离难免要接触到跨域问题,跨域的相关知识请参:跨域问题,解决之道   在Django和Vue前后端分离的时候也会遇到跨域的问题,因为刚刚接触Django还不太了解,今天花了好长的时间,查阅了 ...

随机推荐

  1. vue3 区别于 vue2 的“与众不同”

    希望本篇文章能帮你加深对 Vue 的理解,能信誓旦旦地说自己熟练Vue2/3.除此之外,也希望路过的朋友可以帮助我查漏补缺.   区别 生命周期的变化 整体来看,变化不大,只是名字大部分需要 + on ...

  2. 测试杂谈——一条SQL引发的思考

    此篇只是个人记录,相信各位大神早已轻车熟路,不喜勿喷:有错之处,欢迎指正. 有一天收到新人的咨询,是关于sql的问题. 问题1:为什么sql查询的数据与界面展示的不准确: 问题2:为什么sql查询时间 ...

  3. kali换源及安装docker

    kali换源及安装docker 以管理员身份运行. 换源,记得先备份, cp /etc/apt/sources.list /etc/apt/sources.list.bak 然后修改/etc/apt/ ...

  4. Microsoft Edge如何安装去广告插件

    Microsoft Edge如何安装去广告插件 第一步:安装最新版本Edge https://www.microsoft.com/zh-cn/edge?form=MA13DO&OCID=MA1 ...

  5. AFO以后的机房游记

    2019.8.6~8.8 周老师让我讲插头DP,理所当然地到机房备课(tuifei) dl24来了足足19个人.只可惜lsy没来,我们的phy,ljx去了首师附.看不到神仙打架了[哭] 插头DP这玩意 ...

  6. IDEA导入第三方jar包

    IDEA导入第三方jar包 在Module下新建一个Directory,命名为lib或者libs,然后直接将目标jar包文件复制到这个新建的Directory中. 右键选中导入的jar包,选择Add ...

  7. automake的使用2

    前言 如果你的入口文件main.c和依赖的文件不是在同一个目录中的,使用Autotools来管理项目的时候会稍微复杂一下. 在不同的目录下,项目会生成*.a文件的静态连接(静态连接相当于将多个.o目标 ...

  8. 使用git clone 报错curl56 errno 10054解决方法

    使用git clone 报错curl56 errno 10054解决方法 ----------------版权声明:本文为CSDN博主「伽马射线爆」的原创文章,遵循CC 4.0 BY-SA版权协议,转 ...

  9. Java 中 ConcurrentHashMap 的并发度是什么?

    ConcurrentHashMap 把实际 map 划分成若干部分来实现它的可扩展性和线程安 全.这种划分是使用并发度获得的,它是 ConcurrentHashMap 类构造函数的一 个可选参数,默认 ...

  10. 集合迭代器Iterator

    迭代器模式:就是提供一种方法对一个容器对象中的各个元素进行访问,而又不暴露该对象容器的内部细节. 什么是迭代器Iterator? Java集合框架的集合类,我们有时候称之为容器.容器的种类有很多种,比 ...