<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Django + Taro 前后端分離項目實(shí)現(xiàn)企業(yè)微信登錄

          共 4610字,需瀏覽 10分鐘

           ·

          2022-04-10 12:33

          前言

          還是最近在做的一個小項目,后端用的是Django搭配RestFramework做接口,前端第一次嘗試用京東開源的Taro框架來做多端(目前需要做用于企業(yè)微信的H5端和微信小程序)

          本文記錄一下企業(yè)微信登錄的流程,上周看文檔看得頭暈暈的,其實(shí)很簡單,封裝好了就幾行代碼的事~

          兩種方式

          • 一種是先拼接好登錄要用的地址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用來登錄就行

          說是兩種,其實(shí)流程都是一樣的,只不過第一種少去了前端拼接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)

          ????????return?Response({
          ????????????'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ā)體驗非常好 (除了這個框架有一些讓人無語的坑之外)

          前端要實(shí)現(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#id4
          • 企業(yè)微信文檔:https://developer.work.weixin.qq.com/document/path/91335
          • Taro框架文檔:https://taro-docs.jd.com/taro/docs/router


          瀏覽 45
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  淫色手机在线视频 | 操逼网址视频 | 豆花视频在线 | 免费收看一级黄色电影 | 69人妻人人澡人人爽人人精品 |