Django?+?Taro?前后端分離項目實現(xiàn)企業(yè)微信登錄功能
前言
還是最近在做的一個小項目,后端用的是Django搭配RestFramework做接口,前端第一次嘗試用京東開源的Taro框架來做多端(目前需要做用于企業(yè)微信的H5端和微信小程序)
本文記錄一下企業(yè)微信登錄的流程,上周看文檔看得頭暈暈的,其實很簡單,封裝好了就幾行代碼的事~
兩種方式
- 一種是先拼接好登錄要用的地址
authorize_url
,回調(diào)地址設(shè)置成h5應(yīng)用的網(wǎng)頁入口,然后把authorize_url
設(shè)置為企業(yè)微信里的應(yīng)用主頁就行,然后直接提取鏈接里的code - 另一種是在應(yīng)用里拼接
authorize_url
地址,回調(diào)地址同樣設(shè)置成h5應(yīng)用的網(wǎng)頁入口,然后應(yīng)用里去請求authorize_url
,然后提取鏈接里的code用來登錄就行
說是兩種,其實流程都是一樣的,只不過第一種少去了前端拼接authorize_url
以及首次請求的操作,為了方便起見,本文推薦使用第一種
思路
假設(shè)前端地址是http://xxx.com
,那么我們用后端生成的企業(yè)微信登錄地址中會把前端地址作為回調(diào)地址傳入,在企業(yè)微信中訪問登錄地址之后,回跳轉(zhuǎn)到我們的前端地址,并在路徑中附上參數(shù)code,形式如下:
http://xxx.com?code=dkwawen123j13bk1
所以前端要做的就是拿到這串code,并提交給后端,讓后端拿code去微信服務(wù)器換用戶信息,就這樣~
后端代碼
企業(yè)微信登錄的接口已經(jīng)集成在我的「DjangoStarter」項目模板中,可以直接食用~
后端使用的是wechatpy這個庫,非常好用,封裝了微信開發(fā)的常用功能~
下面寫一下兩個關(guān)鍵的方法
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): """微信企業(yè)號相關(guān)認(rèn)證服務(wù)""" client = WeChatClient( settings.WECHAT_WORK_CONFIG['CORP_ID'], settings.WECHAT_WORK_CONFIG['SECRET'], ) @swagger_auto_schema(operation_summary='獲取微信企業(yè)號登錄鏈接') @action(detail=False) def get_authorize_url(self, request): return Response({ # todo 這里要寫上前端應(yīng)用入口地址 '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='從微信企業(yè)號服務(wù)器獲取到的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登錄狀態(tài) 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': '企業(yè)微信登錄成功',
寫完接口配置一下路由(這里就不重復(fù)了)
然后請求這個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" } }
比如我上面寫的應(yīng)用入口地址是http://xxx.com
,那么得到的企業(yè)微信登錄地址就是
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
各個參數(shù)的意義看企業(yè)微信官方文檔就行,我們不用細(xì)究
企業(yè)微信應(yīng)用配置
接下來我們把這個地址設(shè)置成企業(yè)微信應(yīng)用的主頁
如圖
同時還得設(shè)置一下「可信域名」,在同個頁面的最下方「開發(fā)者接口」處,把前端應(yīng)用部署所在的服務(wù)器域名和端口(80就不用)填上去就行~
這樣應(yīng)用配置就好了
前端代碼
前端用的是京東開源的Taro框架,我前一篇文章寫到我終于用上了React,說的就是在Taro開發(fā)里用React+TypeScript,開發(fā)體驗非常好 (除了這個框架有一些讓人無語的坑之外)
前端要實現(xiàn)的就是從路徑參數(shù)里取出code
我們看到,Taro官方文檔就有關(guān)于路由參數(shù)的處理
所以可以這樣寫來獲取code(函數(shù)式組件寫法)
import { getCurrentInstance } from '@tarojs/taro' let code getCurrentInstance().router?.params['code']
然而!這樣在普通頁面跳轉(zhuǎn)是可以的
比如這種形式
http://xxx.com/#/pages/index/index?code=abc
但人家微信登錄回調(diào)跳轉(zhuǎn)的地址形式是這樣
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
企業(yè)微信文檔:https://developer.work.weixin.qq.com/document/path/91335
Taro框架文檔:https://taro-docs.jd.com/taro/docs/router
到此這篇關(guān)于Django + Taro 前后端分離項目實現(xiàn)企業(yè)微信登錄 功能的文章就介紹到這了,更多相關(guān)Django前后端分離登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python3.6 如何將list存入txt后再讀出list的方法
這篇文章主要介紹了python3.6 如何將list存入txt后再讀出list的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07django2用iframe標(biāo)簽完成網(wǎng)頁內(nèi)嵌播放b站視頻功能
這篇文章主要介紹了django2 用iframe標(biāo)簽完成 網(wǎng)頁內(nèi)嵌播放b站視頻功能,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06使用Python快速實現(xiàn)文件共享并通過內(nèi)網(wǎng)穿透技術(shù)公網(wǎng)訪問
數(shù)據(jù)共享作為和連接作為互聯(lián)網(wǎng)的基礎(chǔ)應(yīng)用,不僅在商業(yè)和辦公場景有廣泛的應(yīng)用,對于個人用戶也有很強的實用意義,今天,筆者就為大家介紹,如何使用python這樣的簡單程序語言,在自己的電腦上搭建一個共享文件服務(wù)器,需要的朋友可以參考下2023-10-10