Django + Taro 前后端分离项目实现企业微信登录
前言
还是最近在做的一个小项目,后端用的是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都有了,后面就不用多说了~
参考资料
- wechatpy库文档:http://docs.wechatpy.org/zh_CN/stable/oauth.html#id4
- 企业微信文档:https://developer.work.weixin.qq.com/document/path/91335
- Taro框架文档:https://taro-docs.jd.com/taro/docs/router
Django + Taro 前后端分离项目实现企业微信登录的更多相关文章
- nginx+vue+uwsgi+django的前后端分离项目部署
Vue+Django前后端分离项目部署,nginx默认端口80,数据提交监听端口9000,反向代理(uwsgi配置)端口9999 1.下载项目文件(统一在/opt/luffyproject目录) (1 ...
- 前后端分离项目shiro的未登录和权限不足
在前后端分离的项目中.前端代码和后端代码几乎不在同一个目录下,甚至不是在一台服务器上:我这个项目部署在linux.同一台服务器,不同目录下:所有的页面跳转由前台路由,后台只是提供返回的数据: 干货↓ ...
- uwsgi加nginx部署django restframework前后端分离项目
一.uwsgi和nginx简介 1.uwsgi(摘抄于百度百科): uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与 ...
- Django+Vue前后端分离项目的部署
部署静态文件: 静态文件有两种方式 1:通过django路由访问 2:通过nginx直接访问 方式1: 需要在根目录的URL文件中增加 url(r'^$', TemplateView.as_view( ...
- 【转】python+django+vue搭建前后端分离项目
https://www.cnblogs.com/zhixi/p/9996832.html 以前一直是做基于PHP或JAVA的前后端分离开发,最近跟着python风搭建了一个基于django的前后端分享 ...
- python+django+vue搭建前后端分离项目
以前一直是做基于PHP或JAVA的前后端分离开发,最近跟着python风搭建了一个基于django的前后端分享项目 准备工作:IDE,[JetBrains PyCharm2018][webpack 3 ...
- Win10环境前后端分离项目基于Vue.js+Django+Python3实现微信(wechat)扫码支付流程(2021年最新攻略)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_182 之前的一篇文章:mpvue1.0+python3.7+Django2.0.4实现微信小程序的支付功能,主要介绍了微信小程序内 ...
- 海纳百川无所不容,Win10环境下使用Docker容器式部署前后端分离项目Django+Vue.js
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_179 随着现代化产品研发的不断推进,我们会发现,几乎每个产品线都会包含功能各异的服务,而且服务与服务之间存在也会存在着错综复杂的依 ...
- 解决Django+Vue前后端分离的跨域问题及关闭csrf验证
前后端分离难免要接触到跨域问题,跨域的相关知识请参:跨域问题,解决之道 在Django和Vue前后端分离的时候也会遇到跨域的问题,因为刚刚接触Django还不太了解,今天花了好长的时间,查阅了 ...
随机推荐
- LGP7840题解
给出一种新的理解方式,本质上和正解是一致的. 首先我们现在已经有了一个森林,我们现在要给他加一条边,加哪一条边是最优的呢? 假设加的边是 \((u,v)\),那么 \(((d[u]+1)^2-d[u] ...
- AT1219题解
题意 设 \(a\) 的价值为 \(a \times cnt_a\)(\(cnt_a\) 为 \(a\) 在区间中出现的次数),求区间种某种元素,使得这种元素的价值最大. 因为设计出现元素的次数,所以 ...
- m3u8文件合并处理
m3u8文件合并处理 简介 M3U8 是 Unicode 版本的 M3U,用 UTF-8 编码."M3U" 和 "M3U8" 文件都是苹果公司使用的 HTTP ...
- Linux移植实际操作一
@ 目录 *前言 目前看了很多关于"Linux移植"的的各种教程.书籍,看完发现不过是对已有板子.已有驱动进行启用.禁用.参数修改.只能叫做"Linux配置". ...
- java的https的get请求
package com.wl.webservice; import java.io.InputStream; import java.net.HttpURLConnection; import jav ...
- [转载]SQL注入绕过WAF的方法总结
基本/简单绕过方法: 1.注释符 http://www.0dayhack.com/index.php?page_id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3,4-. 2.使用 ...
- K8S原来如此简单(五)Metrics Server与HPA
什么是HPA https://kubernetes.io/zh/docs/tasks/run-application/horizontal-pod-autoscale/ 我们前面有通过kubectl ...
- 半吊子菜鸟学Web开发 -- PHP学习5-数据库
数据库 1 进行数据库操作的步骤 连接数据库 mysqli_connect 选择数据库 mysqli_select_db 设置文件编码 mysqli_query("set name utf- ...
- 匿名内部类编译生成的class文件
一.问题描述 跳槽到的新公司,相比原来的公司,软件开发非常不规范,经常各种坑.项目部署到生产现场之后,出现问题,我在修改之后编译生成class文件,然后将class文件发给现场的技术支持,技术支持将c ...
- java-設計模式-生成器
生成器模式Bulider 使你能够分步骤创建复杂对象. 该模式允许你使用相同的创建代码生成不同类型和形式的对象. 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示. 将一个复杂的 ...