uni-app 微信小程式授權登入

2022-01-03 19:00:09

在這裡插入圖片描述

一、appID相關申請和設定
1. appid獲取方式

登入微信公眾平臺
官網連結:https://mp.weixin.qq.com/
第一次需要小夥伴們點選註冊按鈕,進行註冊,如果有賬號,直接掃描登入即可
在這裡插入圖片描述

官網小程式連結:

在這裡插入圖片描述

2. appID設定

在manifest.json中輸入申請的微信小程式id
在這裡插入圖片描述

二、獲取使用者基礎資料

這裡給小夥伴們演示二種api

2.1. 獲取使用者資訊

可以使用uni.getUserProfile請求使用者授權獲取使用者資訊, 也可以使用uni.getUserInfo獲取
在這裡插入圖片描述
授權成功後獲取到的使用者資訊在userInfo中:
在這裡插入圖片描述

  • 頁面部分:
  <button class="login-btn" type="primary" @click="getUserInfo">
        微信使用者一鍵登入
      </button>
  • js部分:

 methods: {
    getUserInfo() {
      uni.getUserInfo({
        provider: 'weixin',
        success: (res) => {
          console.log('getUserInfo', res);
        },
      });
    },
   }
  • 獲取的使用者基礎資料(無openid=》微信使用者唯一標識)
    在這裡插入圖片描述
2.2. 獲取使用者資訊2

可以使用uni.getUserInfo請求使用者授權獲取使用者資訊

  • 頁面一樣,js部分:
   getUserInfo() {
      uni.getUserProfile({
        desc: '登入後可同步資料',
        lang: 'zh_CN',
        success: (res) => {
          console.log('getUserProfile', res);
        },
      });
    },
  • 獲取的使用者基礎資料(無openid=》微信使用者唯一標識)
    在這裡插入圖片描述
    總結:uni.getUserProfile和uni.getUserInfo 二個api獲取的使用者資料基本一樣,都無openid=》微信使用者唯一標識。
三、呼叫登入api
3.1. 登入api

使用uni.login方法,provider引數輸入’weixin’,成功的返回值中如果errMsg=「login:ok」 代表成功,
微信小程式端會返回一個code字串
在這裡插入圖片描述

3.2. 案例程式碼
      uni.login({
            provider: 'weixin',
            success: (res) => {
              console.log('res-login', res);
              this.code = res.code;
              console.log('code', res.code);
              if (res.errMsg == 'login:ok') {
              //TODO 獲取code 攜帶code引數呼叫後端介面}
四、獲取唯一標識資訊
4.1. 官網檔案

官網檔案
使用獲取到的code請求微信登入介面,獲取 openid 和 session_key
在這裡插入圖片描述

4.2. 介面簡述

在這裡插入圖片描述

請求方式:GET
APPID:小程式唯一標識,上面有獲取方式
SECRET:小程式唯一標識的祕鑰,上面參考APPID獲取方式,就在他的下面
JSCODE:這個前端呼叫  uni.login獲取
GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

在這裡插入圖片描述

五、繫結使用者 實現登入

獲取到微信使用者的唯一id後,就可以繫結至自己系統中的使用者,我的做法是在使用者表中加入weixinId欄位,跳轉至自己的使用者繫結介面,如果使用者選擇繫結微信,則更新該行使用者資料的weixinId。下次使用者使用微信登入時,如果通過openId能夠查詢到一條使用者資料,說明已經繫結,則登入該使用者

5.1. 程式碼案例(未封裝)
  • 前端部分:
 /**
     *
     * 獲取使用者資訊
     */
    getUserInfo() {
      // 展示載入框
      uni.showLoading({
        title: '載入中',
      });
      uni.getUserProfile({
        desc: '登入後可同步資料',
        success: async (obj) => {
          console.log('obj', obj);
          // 呼叫 action ,請求登入介面
          // await this.login(obj);
          uni.login({
            provider: 'weixin',
            success: (res) => {
              console.log('res-login', res);
              this.code = res.code;
              console.log('code', res.code);
              if (res.errMsg == 'login:ok') {
                uni
                  .request({
                    url:
                      'http://127.0.0.1:8080/wxh5/wx/user/' +
                      'wx55822xxxx75e422' +
                      '/login/',
                    data: {
                      code: this.code,
                    },
                  })
                  .then((res) => {
                  //獲取到 openid 和 session_k後,自己的邏輯
                    console.log('授權登入', res[1].data);
                    console.log(res[1].data.openid);
                    console.log(res[1].data.session_key);
                    // DoSomeThing.................
                  });
                console.log('res', res);
              }
            },
          });
        },
        fail: () => {
          uni.showToast({
            title: '授權已取消',
            icon: 'error',
            mask: true,
          });
        },
        complete: () => {
          // 隱藏loading
          uni.hideLoading();
        },
      });
    },
  • 後端部分
   @GetMapping("/login")
    public String login(@PathVariable String appid, String code) {
        if (StringUtils.isBlank(code)) {
            return "empty jscode";
        }

        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        try {
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
            this.logger.info(session.getSessionKey());
            this.logger.info(session.getOpenid());
            //TODO 可以增加自己的邏輯,關聯業務相關資料
            return JsonUtils.toJson(session);
        } catch (WxErrorException e) {
            this.logger.error(e.getMessage(), e);
            return e.toString();
        }
    }
5.2. 程式碼案例(封裝)
  /**
     *
     * 獲取使用者資訊
     */
    getUserInfo() {
      // 展示載入框
      uni.showLoading({
        title: '載入中',
      });
      uni.getUserProfile({
        desc: '登入後可同步資料',
        success: async (obj) => {
          // this.userInfo = obj.userInfo;
          // 呼叫 action ,請求登入介面
          uni.login({
            provider: 'weixin',
            success: async (res) => {
              this.code = res.code;
              // console.log('登入獲取code', res.code);
              if (res.errMsg == 'login:ok') {
                await this.loginAuth({
                  userProfile: obj,
                  appid: 'wx558xxxxxxxxxxxxxxx2',
                  code: this.code,
                });
              }
            },
          });
        },
        fail: () => {
          uni.showToast({
            title: '授權已取消',
            icon: 'error',
            mask: true,
          });
        },
        complete: () => {
          // 隱藏loading
          uni.hideLoading();
        },
      });
    },
  },

user.js

/**
 * 微信使用者授權登入,攜帶appid和code引數,呼叫後端介面獲取Openid
 */
export function loginAuth(data) {
  return request({
    url: '/wx/user/' + data.appid + '/login/',
    data: {
      code: data.code,
    },
  });
}

vuex user模組(user.js)

  // 微信使用者授權登入,攜帶appid和code引數,呼叫後端介面獲取Openid
    async loginAuth(context, data) {
      console.log('data', data);
      const userInfo = data.userProfile;
      const { content: res } = await loginAuth({
        appid: data.appid,
        code: data.code,
      });

      // 解析後端傳送過來的json物件
      const userAuthInfo = JSON.parse(res);
      const openid = userAuthInfo.openid;
      // console.log('sessionKey', userAuthInfo.sessionKey);
      console.log('openid', openid);

      // 儲存到vuex中,通過commit
      this.commit('user/setOpenid', userAuthInfo.openid);
      this.commit('user/setUserInfo', JSON.parse(userInfo.rawData));
    },

在這裡插入圖片描述
在這裡插入圖片描述

六、專案開源地址
6.1. 前端

applet-chock-in

6.2. 後端

weixin-java-miniapp