国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

微信小程序之微信授權(quán)登入及授權(quán)的流程講解

這篇具有很好參考價(jià)值的文章主要介紹了微信小程序之微信授權(quán)登入及授權(quán)的流程講解。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

一、流程講解

1. 圖解

2. 講解

二、官方登入

wxLogin

wx.getUserProfile

代碼

三、數(shù)據(jù)交互授權(quán)登入

1. 前端

2. 后端代碼


一、流程講解

1. 圖解

微信小程序授權(quán)登錄,微信小程序,微信,小程序,javascript,前端,intellij-idea

2. 講解

這張圖片是關(guān)于微信小程序授權(quán)登錄的流程圖。流程圖展示了使用微信官方提供的登錄能力來(lái)獲取用戶身份標(biāo)識(shí)的過(guò)程。下面是對(duì)流程圖中的一些關(guān)鍵步驟的解釋:

1. 小程序通過(guò)微信官方提供的登錄能力獲取微信提供的用戶身份標(biāo)識(shí),以便在小程序內(nèi)建立用戶體系。

2. 開(kāi)發(fā)者需要在小程序中調(diào)用wx.login()方法來(lái)獲取一個(gè)臨時(shí)的code,該code是一個(gè)臨時(shí)的字符串,再通過(guò)wx.request()?發(fā)起網(wǎng)絡(luò)請(qǐng)求,將 code 傳給后臺(tái)服務(wù)端。

3. 開(kāi)發(fā)者服務(wù)器通過(guò)發(fā)送code及AppID(小程序ID)AppSecret(小程序密鑰)[ 后面發(fā)送的ID對(duì)于微信接口服務(wù)來(lái)說(shuō)是唯一標(biāo)識(shí) ]調(diào)用微信接口服務(wù)(Wechat Http Api),以獲取session_keyopenid等信息。session_key指的是當(dāng)前的登錄請(qǐng)求,是一次會(huì)話的標(biāo)識(shí)。

4. 開(kāi)發(fā)者服務(wù)器將session_key和openid ( 微信接口轉(zhuǎn)過(guò)來(lái)的openid對(duì)于3微信小程序來(lái)說(shuō)是授權(quán)的唯一標(biāo)識(shí) )?等用戶信息與自定義登錄態(tài)關(guān)聯(lián)起來(lái),返回自定義登錄態(tài)給小程序。

5. 小程序在后續(xù)的業(yè)務(wù)請(qǐng)求中,可以攜帶自定義登錄態(tài)來(lái)向開(kāi)發(fā)者服務(wù)器發(fā)起請(qǐng)求,以獲取業(yè)務(wù)數(shù)據(jù)。

6. 開(kāi)發(fā)者服務(wù)器通過(guò)驗(yàn)證自定義登錄態(tài),返回相應(yīng)的業(yè)務(wù)數(shù)據(jù)給小程序。

總的來(lái)說(shuō),微信小程序授權(quán)登錄的流程包括小程序端調(diào)用wx.login()方法獲取臨時(shí)code,開(kāi)發(fā)者服務(wù)器通過(guò)code+AppID+AppSecret獲取session_key和openid等信息,并將其與自定義登錄態(tài)關(guān)聯(lián)起來(lái),最后小程序可以使用自定義登錄態(tài)來(lái)向開(kāi)發(fā)者服務(wù)器發(fā)起業(yè)務(wù)請(qǐng)求。

二、官方登入

在官方文檔中,有通過(guò)授權(quán)登入的方法及代碼,我這里將其復(fù)制到項(xiàng)目中,進(jìn)行一個(gè)演示。

其中有兩個(gè)方法,有分別不同的用戶體驗(yàn)及安全問(wèn)題。以下就給大家演示:

  • wxLogin

調(diào)用接口獲取登錄憑證(code)。通過(guò)憑證進(jìn)而換取用戶登錄態(tài)信息,包括用戶在當(dāng)前小程序的唯一標(biāo)識(shí)(openid)、微信開(kāi)放平臺(tái)賬號(hào)下的唯一標(biāo)識(shí)(unionid,若當(dāng)前小程序已綁定到微信開(kāi)放平臺(tái)賬號(hào))及本次登錄的會(huì)話密鑰(session_key)等。用戶數(shù)據(jù)的加解密通訊需要依賴會(huì)話密鑰完成。

參數(shù)了解 :

屬性 類型 默認(rèn)值 必填 說(shuō)明 最低版本
timeout number 超時(shí)時(shí)間,單位ms 1.9.90
success function 接口調(diào)用成功的回調(diào)函數(shù)
fail function 接口調(diào)用失敗的回調(diào)函數(shù)
complete function

接口調(diào)用結(jié)束的回調(diào)函數(shù)(調(diào)用成功、失敗都會(huì)執(zhí)行)

code string 用戶登錄憑證(有效期五分鐘)。開(kāi)發(fā)者需要在開(kāi)發(fā)者服務(wù)器后臺(tái)調(diào)用?code2Session,使用 code 換取 openid、unionid、session_key 等信息

演示效果 :?

微信小程序授權(quán)登錄,微信小程序,微信,小程序,javascript,前端,intellij-idea

由操作可看出,該方法對(duì)于用戶的體驗(yàn)及安全性問(wèn)題有所欠缺,點(diǎn)擊就直接獲取到了用戶的信息,進(jìn)行了一個(gè)顯示,這個(gè)方法官方已經(jīng)不推薦了。

  • wx.getUserProfile

獲取用戶信息。頁(yè)面產(chǎn)生點(diǎn)擊事件(例如?button?上?bindtap?的回調(diào)中)后才可調(diào)用,每次請(qǐng)求都會(huì)彈出授權(quán)窗口,用戶同意后返回?userInfo。該接口用于替換?wx.getUserInfo,詳見(jiàn)?用戶信息接口調(diào)整說(shuō)明。

參數(shù)了解 :

屬性 類型 默認(rèn)值 必填 說(shuō)明?
lang string en 顯示用戶信息的語(yǔ)言
desc string 聲明獲取用戶個(gè)人信息后的用途,不超過(guò)30個(gè)字符
success function 接口調(diào)用成功的回調(diào)函數(shù)
fail function
接口調(diào)用失敗的回調(diào)函數(shù)
complete function 接口調(diào)用結(jié)束的回調(diào)函數(shù)(調(diào)用成功、失敗都會(huì)執(zhí)行)

演示效果 :?

微信小程序授權(quán)登錄,微信小程序,微信,小程序,javascript,前端,intellij-idea

相比之下,該方法要更有用戶體驗(yàn)及提高安全問(wèn)題。

信息了解 :

用戶信息接口調(diào)整說(shuō)明https://developers.weixin.qq.com/community/develop/doc/000cacfa20ce88df04cb468bc52801?highLine=login

  • 代碼

index.wxml

<!--pages/index/index.wxml-->
<view>
  <button wx:if="{{canIUseGetUserProfile}}" type="primary" class="wx-login-btn" bindtap="getUserProfile">微信直接登錄1</button>
  <button wx:else open-type="getUserInfo" type="primary" class="wx-login-btn" bindgetuserinfo="wxLogin">微信直接登錄2</button>
  <image mode="scaleToFill" src="{{userInfo.avatarUrl}}" />
  <text>昵稱:{{userInfo.nickName}}</text>
</view>

index.js

// pages/index/index.js
Page({
  data: {
    userInfo: {},
    canIUseGetUserProfile: true,
  },
  onLoad() {
    // if (wx.getUserProfile) {
    //   this.setData({
    //     canIUseGetUserProfile: true
    //   })
    // }
  },
  getUserProfile(e) {
    console.log('getUserProfile')
    // 推薦使用 wx.getUserProfile 獲取用戶信息,開(kāi)發(fā)者每次通過(guò)該接口獲取用戶個(gè)人信息均需用戶確認(rèn)
    // 開(kāi)發(fā)者妥善保管用戶快速填寫(xiě)的頭像昵稱,避免重復(fù)彈窗
    wx.getUserProfile({
      desc: '用于完善會(huì)員資料', // 聲明獲取用戶個(gè)人信息后的用途,后續(xù)會(huì)展示在彈窗中,請(qǐng)謹(jǐn)慎填寫(xiě)
      success: (res) => {
        console.log(res);
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    })
  },
  wxLogin: function(e) {
    // debugger
    console.log('wxLogin')
    console.log(e.detail.userInfo);
    this.setData({
      userInfo: e.detail.userInfo
    })
    if (e.detail.userInfo == undefined) {
      app.globalData.hasLogin = false;
      util.showErrorToast('微信登錄失敗');
      return;
    }
  },
  /**
   * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面顯示
   */
  onShow() {

  },

  /**
   * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面隱藏
   */
  onHide() {

  },

  /**
   * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面卸載
   */
  onUnload() {

  },

  /**
   * 頁(yè)面相關(guān)事件處理函數(shù)--監(jiān)聽(tīng)用戶下拉動(dòng)作
   */
  onPullDownRefresh() {

  },

  /**
   * 頁(yè)面上拉觸底事件的處理函數(shù)
   */
  onReachBottom() {

  },

  /**
   * 用戶點(diǎn)擊右上角分享
   */
  onShareAppMessage() {

  }
})

js文件中?canIUseGetUserProfile 屬性值為 : true時(shí),就是wx.getUserProfile方法,當(dāng)為false,就是wxLogin方法。

三、數(shù)據(jù)交互授權(quán)登入

以下代碼是基于我博客中進(jìn)行的續(xù)寫(xiě) :?微信小程序開(kāi)發(fā)之后臺(tái)數(shù)據(jù)交互及wxs應(yīng)用

1. 前端

在項(xiàng)目中編寫(xiě) api.js 文件中的請(qǐng)求訪問(wèn)地址

// 以下是業(yè)務(wù)服務(wù)器API地址
 // 本機(jī)開(kāi)發(fā)API地址
var WxApiRoot = 'http://localhost:8080/oapro/wx/';
// 測(cè)試環(huán)境部署api地址
// var WxApiRoot = 'http://192.168.191.1:8080/oapro/wx/';
// 線上平臺(tái)api地址
//var WxApiRoot = 'https://www.oa-mini.com/demo/wx/';

module.exports = {
  IndexUrl: WxApiRoot + 'home/index', //首頁(yè)數(shù)據(jù)接口
  SwiperImgs: WxApiRoot+'swiperImgs',
  MettingInfos: WxApiRoot+'meeting/list',
  AuthLoginByWeixin: WxApiRoot + 'auth/login_by_weixin', //微信登錄
  UserIndex: WxApiRoot + 'user/index', //個(gè)人頁(yè)面用戶相關(guān)信息
  AuthLogout: WxApiRoot + 'auth/logout', //賬號(hào)登出
  AuthBindPhone: WxApiRoot + 'auth/bindPhone' //綁定微信手機(jī)號(hào)
};

注意 :? ?需要對(duì)應(yīng)后臺(tái)的請(qǐng)求地址之后進(jìn)行數(shù)據(jù)的訪問(wèn)。

個(gè)人中心

在個(gè)人中心頁(yè)面的 index.wxml 文件中進(jìn)行編寫(xiě):

<view class="page-container">
    <view class="user-info-container">
        <view class="user-info"  bindtap="goLogin">
            <image class="user-img" mode="scaleToFill" src="{{userInfo.avatarUrl}}" />
            <text class="user-info-name">{{userInfo.nickName}}</text>
        </view>
        <image class="user-update" src="/static/tabBar/component.png" bindtap='goPages' data-url='/pages/ucenter/user/user'/>
    </view>

    <view class="boundary" />
    <view class="cells-container">
        <view class="cell-wrap">
            <image class="cell-icon" src="/static/tabBar/sdk.png" />
            <text class="cell-text">我主持的會(huì)議</text>
            <view class="cell-right">
                <view class="cell-list-num">{{metting_pubs}}</view>
                <view class="cell-arrow"></view>
            </view>
        </view>
        <view class="cell-wrap">
            <image class="cell-icon" src="/static/tabBar/sdk.png" />
            <text class="cell-text">我參與的會(huì)議</text>
            <view class="cell-right">
                <view class="cell-list-num">{{metting_joins}}</view>
                <view class="cell-arrow"></view>
            </view>
        </view>
    </view>
    <view class="boundary" />
    <view class="cells-container">
        <view class="cell-wrap">
            <image class="cell-icon" src="/static/tabBar/sdk.png" />
            <text class="cell-text">我發(fā)布的投票</text>
            <view class="cell-right">
                <view class="cell-list-num">1</view>
                <view class="cell-arrow"></view>
            </view>
        </view>
        <view class="cell-wrap">
            <image class="cell-icon" src="/static/tabBar/sdk.png" />
            <text class="cell-text">我參與的投票</text>
            <view class="cell-right">
                <view class="cell-list-num">10</view>
                <view class="cell-arrow"></view>
            </view>
        </view>
    </view>
    <view class="boundary" />
    <view class="cells-container">
        <view class="cell-wrap">
            <image class="cell-icon" src="/static/tabBar/template.png" />
            <text class="cell-text">消息</text>
            <view class="cell-right">
                <view class="cell-list-num"></view>
                <view class="cell-arrow"></view>
            </view>
        </view>
        <view class="cell-wrap">
            <image class="cell-icon" src="/static/tabBar/component.png" />
            <text class="cell-text">設(shè)置</text>
            <view class="cell-right">
                <view class="cell-list-num"></view>
                <view class="cell-arrow"></view>
            </view>
        </view>
    </view>
</view>

index.js 中編寫(xiě)數(shù)據(jù)請(qǐng)求及方法

// pages/ucenter/index/index.js
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
const app = getApp();
Page({

    /**
     * 頁(yè)面的初始數(shù)據(jù)
     */
    data: {
        userInfo: {
            nickName: '點(diǎn)擊登錄',
            avatarUrl: '/static/images/avatar.png'
        },
        hasLogin: false,
        metting_pubs: '',
        metting_joins: ''
    },

    /**
     * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面加載
     */
    onLoad(options) {

    },


    /**
     * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面顯示
     */
    onShow() {
        this.getUserInfo();
    },
    getUserInfo() {
      // console.log('ucenter.index.app.globalData.hasLogin='+app.globalData.hasLogin)
        //獲取用戶的登錄信息
        if (app.globalData.hasLogin) {
            let userInfo = wx.getStorageSync('userInfo');
            this.setData({
                userInfo: userInfo,
                hasLogin: true
            });
            //查詢個(gè)人統(tǒng)計(jì)信息
            util.request(api.UserIndex).then(res => {
                if (res.errno === 0) {
                    this.setData({
                        metting_pubs: res.data.metting_pubs,
                        metting_joins: res.data.metting_joins
                    });
                }
            });
        }
    },
    goLogin() {
        if (!this.data.hasLogin) {
            wx.navigateTo({
                url: "/pages/auth/login/login"
            });
        }
    },
    /**
     * 頁(yè)面跳轉(zhuǎn)
     */
    goPages: function (e) {
        if (this.data.hasLogin) {
            wx.navigateTo({
                url: e.currentTarget.dataset.url
            });
        } else {
            wx.navigateTo({
                url: "/pages/auth/login/login"
            });
        };
    }

})

創(chuàng)建一個(gè)用戶登入后的設(shè)置頁(yè)面為 : user

user.wxml

<!--pages/ucenter/user/user.wxml-->
<form bindsubmit="formSubmit">
    <view class='personal-data'>
        <view class='list'>
            <view class='item acea-row row-between-wrapper'>
                <view>頭像</view>
                <view class='pictrue'>
                    <image src='{{userInfo.avatarUrl}}'></image>
                </view>
            </view>
            <view class='item acea-row row-between-wrapper'>
                <view>名字</view>
                <view class='input'><input type='text' disabled='true' name='nickname' value='{{userInfo.nickName}}'></input></view>
            </view>
            <view class='item acea-row row-between-wrapper'>
                <view>手機(jī)號(hào)碼</view>
                <button name='phone' class='phoneW' value='{{userInfo.phone}}' wx:if="{{!userInfo.phone}}" bindgetphonenumber="getPhoneNumber" hover-class='none' open-type='getPhoneNumber'>
                    點(diǎn)擊獲取
                </button>
                <view class='input acea-row row-between-wrapper' wx:else>
                    <input type='text' disabled='true' name='phone' value='{{userInfo.phone}}' class='id'></input>
                    <text class='iconfont icon-suozi'></text>
                </view>
            </view>
 
            <view class='item acea-row row-between-wrapper'>
                <view>ID號(hào)</view>
                <view class='input acea-row row-between-wrapper'>
                    <input type='text' value='1000{{userInfo.userId}}' disabled='true' class='id'></input>
                    <text class='iconfont icon-suozi'></text>
                </view>
            </view>
        </view>
        <button class='modifyBnt' bindtap="exitLogin">退 出</button>
    </view>
</form>

user.wxss

@import '/static/font/iconfont.wxss';
.personal-data .list {
    margin-top: 15rpx;
    background-color: #fff;
}

.personal-data .list .item {
    padding: 30rpx 30rpx 30rpx 0;
    border-bottom: 1rpx solid #f2f2f2;
    margin-left: 30rpx;
    font-size: 32rpx;
    color: #282828;
}

.personal-data .list .item .phone {
    background-color: #85c43f;
    width: 160rpx;
    height: 56rpx;
    font-size: 24rpx;
    color: #fff;
    line-height: 56rpx;
    border-radius: 32rpx
}

.personal-data .list .item .pictrue {
    width: 88rpx;
    height: 88rpx;
}

.personal-data .list .item .pictrue image {
    width: 100%;
    height: 100%;
    border-radius: 50%;
}

.personal-data .list .item .input {
    width: 415rpx;
    text-align: right;
    color: #868686;
}

.personal-data .list .item .input .id {
    width: 365rpx;
}

.personal-data .list .item .input .iconfont {
    font-size: 35rpx;
}

.personal-data .modifyBnt {
    /* background-color: #85c43f; */
    /* background: linear-gradient(to left right, #85c43f, #fefefd); */
    background: radial-gradient(circle at 50%,#85c43f,#CDDC39);
    font-size: 32rpx;
    color: #fff;
    width: 690rpx;
    height: 90rpx;
    border-radius: 50rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    line-height: 90rpx;
    margin: 76rpx auto 0 auto;
}


.acea-row{display:flex;flex-wrap:wrap;}
.acea-row.row-top{align-items:flex-start;}
.acea-row.row-middle{align-items:center;}
.acea-row.row-bottom{align-items:flex-end;}
.acea-row.row-left{justify-content:flex-start;}
.acea-row.row-center{justify-content:center;}
.acea-row.row-right{justify-content:flex-end;}
.acea-row.row-between{justify-content:space-between;}
.acea-row.row-around{justify-content:space-around;}
.acea-row.row-column{flex-direction:column;}
.acea-row.row-column-between{flex-direction:column;justify-content:space-between;}
.acea-row.row-column-around{flex-direction:column;justify-content:space-around;}
.acea-row.row-center-wrapper{align-items:center;justify-content:center;}
.acea-row.row-between-wrapper{align-items:center;justify-content:space-between;}
view, image, text, navigator {
    box-sizing: border-box;
    padding: 0;
    margin: 0;
}

user.js

var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var user = require('../../../utils/user.js');
var app = getApp();
Page({
 
  /**
   * 頁(yè)面的初始數(shù)據(jù)
   */
  data: {
    userInfo: {},
    hasLogin: false,
    userSharedUrl: ''
  },
 
  /**
      * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面加載
   */
  onLoad: function (options) {
 
  },
  onShow: function () {
    let that = this;
    //獲取用戶的登錄信息
    let userInfo = wx.getStorageSync('userInfo');
    this.setData({
      userInfo: userInfo,
      hasLogin: true
    });
 
  },
  getPhoneNumber: function (e) {
      console.log(e);
    let that = this;
    if (e.detail.errMsg !== "getPhoneNumber:ok") {
      // 拒絕授權(quán)
      return;
    }
 
    if (!this.data.hasLogin) {
      wx.showToast({
        title: '綁定失?。赫?qǐng)先登錄',
        icon: 'none',
        duration: 2000
      });
      return;
    }
 
    util.request(api.AuthBindPhone, {
      iv: e.detail.iv,
      encryptedData: e.detail.encryptedData
    }, 'POST').then(function (res) {
      if (res.errno === 0) {
        let userInfo = wx.getStorageSync('userInfo');
        userInfo.phone = res.data.phone;//設(shè)置手機(jī)號(hào)碼
        wx.setStorageSync('userInfo', userInfo);
        that.setData({
          userInfo: userInfo,
          hasLogin: true
        });
        wx.showToast({
          title: '綁定手機(jī)號(hào)碼成功',
          icon: 'success',
          duration: 2000
        });
      }
    });
  },
  exitLogin: function () {
    wx.showModal({
      title: '',
      confirmColor: '#b4282d',
      content: '退出登錄?',
      success: function (res) {
        if (!res.confirm) {
          return;
        }
 
        util.request(api.AuthLogout, {}, 'POST');
        app.globalData.hasLogin = false;
        wx.removeStorageSync('token');
        wx.removeStorageSync('userInfo');
        wx.reLaunch({
          url: '/pages/index/index'
        });
      }
    })
  }
})

2. 后端代碼

在后臺(tái)編寫(xiě)的控制器,來(lái)進(jìn)行出來(lái)前端的請(qǐng)求及數(shù)據(jù)處理并且反饋帶前端

WxAuthController :?

package com.CloudJun.ssm.wxcontroller;

/**
 * @Autho donkee
 * @Since 2022/6/27
 */

import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.alibaba.fastjson.JSONObject;
import com.CloudJun.ssm.annotation.LoginUser;
import com.CloudJun.ssm.model.UserInfo;
import com.CloudJun.ssm.model.WxLoginInfo;
import com.CloudJun.ssm.model.WxUser;
import com.CloudJun.ssm.service.UserToken;
import com.CloudJun.ssm.service.UserTokenManager;
import com.CloudJun.ssm.service.WxUserService;
import com.CloudJun.ssm.util.JacksonUtil;
import com.CloudJun.ssm.util.ResponseUtil;
import com.CloudJun.ssm.util.UserTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import javax.servlet.http.HttpServletRequest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 鑒權(quán)服務(wù)
 */
@Slf4j
@RestController
@RequestMapping("/wx/auth")
public class WxAuthController {
    @Autowired
    private WxMaService wxService;
    @Autowired
    private WxUserService userService;
    /**
     * 微信登錄
     *
     * @param wxLoginInfo
     *            請(qǐng)求內(nèi)容,{ code: xxx, userInfo: xxx }
     * @param request
     *            請(qǐng)求對(duì)象
     * @return 登錄結(jié)果
     */
    @PostMapping("login_by_weixin")
    public Object loginByWeixin(@RequestBody WxLoginInfo wxLoginInfo, HttpServletRequest request) {

        //客戶端需攜帶code與userInfo信息
        String code = wxLoginInfo.getCode();
        UserInfo userInfo = wxLoginInfo.getUserInfo();
        if (code == null || userInfo == null) {
            return ResponseUtil.badArgument();
        }
        //調(diào)用微信sdk獲取openId及sessionKey
        String sessionKey = null;
        String openId = null;
        try {
            long beginTime = System.currentTimeMillis();
            //
            WxMaJscode2SessionResult result = this.wxService.getUserService().getSessionInfo(code);
//            Thread.sleep(6000);
            long endTime = System.currentTimeMillis();
            log.info("響應(yīng)時(shí)間:{}",(endTime-beginTime));
            sessionKey = result.getSessionKey();//session id
            openId = result.getOpenid();//用戶唯一標(biāo)識(shí) OpenID
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (sessionKey == null || openId == null) {
            log.error("微信登錄,調(diào)用官方接口失?。簕}", code);
            return ResponseUtil.fail();
        }else{
            log.info("openId={},sessionKey={}",openId,sessionKey);
        }
        //根據(jù)openId查詢wx_user表
        //如果不存在,初始化wx_user,并保存到數(shù)據(jù)庫(kù)中
        //如果存在,更新最后登錄時(shí)間
        WxUser user = userService.queryByOid(openId);

        if (user == null) {
            user = new WxUser();
            user.setUsername(openId);
            user.setPassword(openId);
            user.setWeixinOpenid(openId);
            user.setAvatar(userInfo.getAvatarUrl());
            user.setNickname(userInfo.getNickName());
            user.setGender(userInfo.getGender());
            user.setUserLevel((byte) 0);
            user.setStatus((byte) 0);
            user.setLastLoginTime(new Date());
            user.setLastLoginIp(IpUtil.client(request));
            user.setShareUserId(1);

            userService.add(user);

        } else {
            user.setLastLoginTime(new Date());
            user.setLastLoginIp(IpUtil.client(request));
            if (userService.updateById(user) == 0) {
                log.error("修改失敗:{}", user);
                return ResponseUtil.updatedDataFailed();
            }
        }
        // token
        UserToken userToken = null;
        try {
            userToken = UserTokenManager.generateToken(user.getId());
        } catch (Exception e) {
            log.error("微信登錄失敗,生成token失?。簕}", user.getId());
            e.printStackTrace();
            return ResponseUtil.fail();
        }
        userToken.setSessionKey(sessionKey);
        log.info("SessionKey={}",UserTokenManager.getSessionKey(user.getId()));
        Map<Object, Object> result = new HashMap<Object, Object>();
        result.put("token", userToken.getToken());
        result.put("tokenExpire", userToken.getExpireTime().toString());
        userInfo.setUserId(user.getId());
        if (!StringUtils.isEmpty(user.getMobile())) {// 手機(jī)號(hào)存在則設(shè)置
            userInfo.setPhone(user.getMobile());
        }
        try {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            String registerDate = df.format(user.getAddTime() != null ? user.getAddTime() : new Date());
            userInfo.setRegisterDate(registerDate);
            userInfo.setStatus(user.getStatus());
            userInfo.setUserLevel(user.getUserLevel());// 用戶層級(jí)
            userInfo.setUserLevelDesc(UserTypeEnum.getInstance(user.getUserLevel()).getDesc());// 用戶層級(jí)描述
        } catch (Exception e) {
            log.error("微信登錄:設(shè)置用戶指定信息出錯(cuò):"+e.getMessage());
            e.printStackTrace();
        }
        result.put("userInfo", userInfo);


        log.info("【請(qǐng)求結(jié)束】微信登錄,響應(yīng)結(jié)果:{}", JSONObject.toJSONString(result));

        return ResponseUtil.ok(result);
    }
    /**
     * 綁定手機(jī)號(hào)碼
     *
     * @param userId
     * @param body
     * @return
     */
    @PostMapping("bindPhone")
    public Object bindPhone(@LoginUser Integer userId, @RequestBody String body) {
        log.info("【請(qǐng)求開(kāi)始】綁定手機(jī)號(hào)碼,請(qǐng)求參數(shù),body:{}", body);

        String sessionKey = UserTokenManager.getSessionKey(userId);
        String encryptedData = JacksonUtil.parseString(body, "encryptedData");
        String iv = JacksonUtil.parseString(body, "iv");
        WxMaPhoneNumberInfo phoneNumberInfo = null;
        try {
            phoneNumberInfo = this.wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
        } catch (Exception e) {
            log.error("綁定手機(jī)號(hào)碼失敗,獲取微信綁定的手機(jī)號(hào)碼出錯(cuò):{}", body);
            e.printStackTrace();
            return ResponseUtil.fail();
        }
        String phone = phoneNumberInfo.getPhoneNumber();
        WxUser user = userService.selectByPrimaryKey(userId);
        user.setMobile(phone);
        if (userService.updateById(user) == 0) {
            log.error("綁定手機(jī)號(hào)碼,更新用戶信息出錯(cuò),id:{}", user.getId());
            return ResponseUtil.updatedDataFailed();
        }
        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("phone", phone);

        log.info("【請(qǐng)求結(jié)束】綁定手機(jī)號(hào)碼,響應(yīng)結(jié)果:{}", JSONObject.toJSONString(data));
        return ResponseUtil.ok(data);
    }
    /**
     * 注銷登錄
     */
    @PostMapping("logout")
    public Object logout(@LoginUser Integer userId) {
        log.info("【請(qǐng)求開(kāi)始】注銷登錄,請(qǐng)求參數(shù),userId:{}", userId);
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        try {
            UserTokenManager.removeToken(userId);
        } catch (Exception e) {
            log.error("注銷登錄出錯(cuò):userId:{}", userId);
            e.printStackTrace();
            return ResponseUtil.fail();
        }

        log.info("【請(qǐng)求結(jié)束】注銷登錄成功!");
        return ResponseUtil.ok();
    }
}

application.yml 文件中進(jìn)行配置后臺(tái)的數(shù)據(jù)庫(kù)及微信小程序的AppID(小程序ID)及AppSecret(小程序密鑰),來(lái)幫助訪問(wèn)微信的接口服務(wù)。

server:
  port: 8080 #指服器端口號(hào)
  servlet:
    context-path: /oapro

spring:
  datasource:
    #type連接池類型 DBCP,C3P0,Hikari,Druid,默認(rèn)為Hikari
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_oapro?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath*:mapper/*.xml #指定mapper文件位置
  type-aliases-package: com.CloudJun.ssm.model #指定自動(dòng)生成別名所在包

logging:
  level:
    root:  info
    org.springframework:  info
    org.mybatis:  ERROR
    com.CloudJun.ssm.mapper: debug

oa:
  wx:
    app-id: # 這里填寫(xiě)AppID(小程序ID)
    app-secret: # 這里填寫(xiě)AppSecret(小程序密鑰)
    msgDataFormat: JSON

最后后臺(tái)開(kāi)啟服務(wù),在前端進(jìn)行數(shù)據(jù)訪問(wèn)及微信授權(quán)登入

后臺(tái)的服務(wù)開(kāi)起后,可以在模擬器中可以看到的效果 :?

微信小程序授權(quán)登錄,微信小程序,微信,小程序,javascript,前端,intellij-idea文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-752972.html

到了這里,關(guān)于微信小程序之微信授權(quán)登入及授權(quán)的流程講解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【2023最新】微信小程序中微信授權(quán)登錄功能和退出登錄功能實(shí)現(xiàn)講解

    教學(xué)視頻地址: 視頻地址 大家要跟著我的教學(xué)視頻去配套著看代碼,了解整個(gè)登錄流程的實(shí)現(xiàn)思路最重要! 以上是我列出的 主要實(shí)現(xiàn)代碼 , 頁(yè)面樣式那些根據(jù)自己需求去實(shí)現(xiàn) ,我這就不貼了。

    2024年02月08日
    瀏覽(28)
  • mpVue 微信小程序授權(quán)登錄流程(即登錄鑒權(quán)流程)及獲取手機(jī)號(hào)一鍵登錄教程(getPhoneNumber使用)

    mpVue 微信小程序授權(quán)登錄流程(即登錄鑒權(quán)流程)及獲取手機(jī)號(hào)一鍵登錄教程(getPhoneNumber使用)

    微信小程序登錄 鑒權(quán)流程 如下: 因 wx.getUserProfile 與 wx.getUserInfo 接口被收回了,都不能彈出授權(quán)窗口,只能使用頭像昵稱填寫(xiě)能力去獲取微信用戶信息。 在鑒權(quán)頁(yè)面如下操作 : 1、在 onShow 中調(diào)用微信登錄 wx.login 獲取到唯一的code(用來(lái)獲取 openid ); 2、根據(jù) wx.login 獲取的c

    2024年02月12日
    瀏覽(27)
  • SpringCloud微服務(wù)實(shí)戰(zhàn)——搭建企業(yè)級(jí)開(kāi)發(fā)框架:第三方登錄-微信小程序授權(quán)登錄流程設(shè)計(jì)和實(shí)現(xiàn)

    SpringCloud微服務(wù)實(shí)戰(zhàn)——搭建企業(yè)級(jí)開(kāi)發(fā)框架:第三方登錄-微信小程序授權(quán)登錄流程設(shè)計(jì)和實(shí)現(xiàn)

    ??在前面的設(shè)計(jì)和實(shí)現(xiàn)中,我們的微服務(wù)開(kāi)發(fā)平臺(tái)通過(guò)JustAuth來(lái)實(shí)現(xiàn)第三方授權(quán)登錄,通過(guò)集成公共組件,著實(shí)減少了很多工作量,大多數(shù)的第三方登錄直接通過(guò)配置就可以實(shí)現(xiàn)。而在第三方授權(quán)登錄中,微信小程序授權(quán)登錄和APP微信授權(quán)登錄是兩種特殊的第三方授權(quán)登錄

    2024年02月07日
    瀏覽(19)
  • 微信小程序-微信授權(quán)登錄

    微信小程序-微信授權(quán)登錄

    小程序可以通過(guò)微信官方提供的登錄能力方便地獲取微信提供的用戶身份標(biāo)識(shí),快速建立小程序內(nèi)的用戶體系 觸發(fā)授權(quán)登錄 : 用戶在小程序中觸發(fā)登錄操作,通常通過(guò)點(diǎn)擊登錄按鈕或執(zhí)行相關(guān)操作。 授權(quán)彈窗 : 小程序彈出授權(quán)登錄的彈窗,要求用戶授權(quán)小程序訪問(wèn)其微信賬

    2024年02月08日
    瀏覽(24)
  • 微信小程序授權(quán)登錄

    微信小程序授權(quán)登錄

    登錄流程時(shí)序 說(shuō)明: 1.小程序端調(diào)用? wx.login() ?獲取臨時(shí)登錄憑證code?,并回傳到開(kāi)發(fā)者服務(wù)器。 2.服務(wù)器調(diào)用? code2Session ?接口,換取?用戶唯一標(biāo)識(shí) OpenID?和?會(huì)話密鑰 session_key。 之后開(kāi)發(fā)者服務(wù)器可以根據(jù)用戶標(biāo)識(shí)來(lái)生成自定義登錄態(tài),用于后續(xù)業(yè)務(wù)邏輯中前后端交互

    2024年02月07日
    瀏覽(19)
  • 微信小程序——授權(quán)登錄

    在微信小程序中,授權(quán)登錄通常是指用戶允許小程序獲取其微信用戶信息(如昵稱、頭像等)的過(guò)程。以下是微信小程序授權(quán)登錄的基本步驟以及相關(guān)API的使用: 步驟一:獲取用戶授權(quán) 在小程序中,你需要?jiǎng)?chuàng)建一個(gè)按鈕或其他用戶觸發(fā)的UI元素,以觸發(fā)授權(quán)登錄操作。 創(chuàng)建

    2024年02月04日
    瀏覽(89)
  • uniapp(vue3) - 詳解微信小程序平臺(tái)用戶授權(quán)登錄全流程,uniapp v3版本中小程序端開(kāi)發(fā)下用戶點(diǎn)擊登錄后獲取手機(jī)號(hào)/昵稱/性別/頭像等信息完成登錄(提供完整示例代碼,一鍵復(fù)制開(kāi)箱即用)

    uniapp(vue3) - 詳解微信小程序平臺(tái)用戶授權(quán)登錄全流程,uniapp v3版本中小程序端開(kāi)發(fā)下用戶點(diǎn)擊登錄后獲取手機(jī)號(hào)/昵稱/性別/頭像等信息完成登錄(提供完整示例代碼,一鍵復(fù)制開(kāi)箱即用)

    在uniapp(v3)微信小程序端開(kāi)發(fā)中,超詳細(xì)實(shí)現(xiàn)用戶授權(quán)登錄完整功能源碼,用戶授權(quán)后獲取手機(jī)號(hào)/昵稱/頭像/性別等,提供完整思路流程及邏輯講解。 你也可以直接復(fù)制粘貼,然后改下參數(shù)放到你的項(xiàng)目中去就行。 做功能之前,先

    2024年02月05日
    瀏覽(32)
  • 微信小程序授權(quán)流程

    微信小程序授權(quán)流程

    小程序中的部分接口,比如地理位置、錄音、攝像頭、用戶信息等,需要用戶授權(quán)后,才可以調(diào)用。把這些接口按使用范圍分成多個(gè) scope ,用戶選擇對(duì) scope 來(lái)進(jìn)行授權(quán),當(dāng)授權(quán)給一個(gè) scope 之后,其對(duì)應(yīng)的所有接口都可以直接使用。 此類接口調(diào)用時(shí): 如果用戶未接受或拒絕

    2024年02月09日
    瀏覽(22)
  • 微信小程序授權(quán)登錄詳細(xì)解析

    微信小程序授權(quán)登錄詳細(xì)解析

    一、首先在wxml頁(yè)面定義一個(gè)普通按鈕,在用bindtap定義一個(gè)事件 ?二、去到j(luò)s頁(yè)面,使用wx.getUserProfile獲取到用戶信息,主要獲取微信昵稱和微信頭像 ?三、使用wx.login獲取code發(fā)送請(qǐng)求 ? 四、將code、nickName、avatarUrl傳入到后端 ?五、后端接受到code、用戶頭像、用戶昵稱 ?六、

    2024年02月09日
    瀏覽(28)
  • UNIAPP---實(shí)現(xiàn)微信小程序登錄授權(quán)和手機(jī)號(hào)授權(quán)(uniapp做微信小程序)

    UNIAPP---實(shí)現(xiàn)微信小程序登錄授權(quán)和手機(jī)號(hào)授權(quán)(uniapp做微信小程序)

    描述:uniapp開(kāi)發(fā)小程序,先授權(quán)用戶信息后再出現(xiàn)手機(jī)號(hào)授權(quán)的頁(yè)面進(jìn)行手機(jī)號(hào)授權(quán)。完成后返回上一頁(yè)面并把信息存入后臺(tái)以及前臺(tái)緩存中,方便使用。 1.在uniapp的manifest.json進(jìn)行微信小程序配置 2.封裝request請(qǐng)求api.js(如果已封裝可跳過(guò)) 3.封裝微信授權(quán)登錄以及獲取手機(jī)

    2024年02月11日
    瀏覽(36)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包