公眾號H5頁面接入微信登錄流程


公眾號H5頁面接入微信登錄流程

源碼地址

https://gitee.com/szxio/h5_weixin

起步

首先創建一個項目,我們采用uni-app來作為我們的前端框架

環境安裝

全局安裝vue-cli

npm install -g @vue/cli

創建uni-app

使用正式版(對應HBuilderX最新正式版)

vue create -p dcloudio/uni-preset-vue my-project

在安裝過程中選擇默認版本即可

啟動

安裝完成后按照提示進入我們的項目根目錄下執行啟動命令

npm run serve

啟動成功圖

申請測試號

官方文檔

文檔地址

申請測試公眾號

這里我們本地學習,所以可以申請一個測試哈,方便我們快速了解微信相關配置。在實際開發中我們會將我們的網站配置在真正的公眾號中。

1.首先登錄微信公眾平台,選擇一個公眾號登錄,第一次登錄時可能沒有公眾號,我們可以申請注冊一個訂閱號即可。

登錄進來后點擊下圖標示菜單可以申請一個測試號

點擊之后我要求我們登錄,我們掃碼登錄一下即可,然后可以看到如下界面

這里可以看到我們公眾號的appIDappsecret。另外由於我之前設置過相關配置,所以這里的 接口配置信息 和 JS接口安全域名 有內容,第一次申請的沒有,不過不影響我們本次教程的后續開發。當我們有需要時可以重新在這個頁面中去設置相關接口信息

配置授權回調頁面域名

在測試號管理頁面往下滑可以看到下面的配置項

設置我們項目的啟動地址,由於是測試號,所以這里可以配置IP地址

注意:測試號可以配置ip地址,正式號只能配置域名

給測試號配置菜單

安裝axiox

npm install axios --save

獲取AccessToken

調用如下地址即可獲取AccessToken

GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

官方文檔地址

請求如下接口獲取Access token,這個Access token有7200秒的有效期,並且接口每天限制2000次請求,所以一般由后端去請求該接口並保存起來,並且設置定時刷新。但是由於現在學習階段,所以我們前端可以直接請求

新建 src\util\getTonken.js 文件,編寫如下代碼

import http from "axios"
const APPID = "這里替換成測試號的APPID"
const APPSECRET = "這里替換成測試號的APPSECRET"


// 更新tonken
function updateToken() {
    return new Promise((resolve, reject) => {
        http.get(`/weixin/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`).then(res => {
            resolve(res.data.access_token)
        }).catch(err => {
            reject(err)
        })
    })
}

// 獲取Tonken
export function getToKen() {
    return new Promise(async (resolve, reject) => {
        // 從緩存中讀取token
        let stroagetoken = uni.getStorageSync('accessToken')
        // 如果緩存中有token,則直接返回緩存中的token
        if (stroagetoken) {
            console.log('緩存獲取的token');
            // 返回結果
            resolve(stroagetoken)
        } else {
            // 如果緩存沒有token,則走接口重新獲取新的token
            let token = await updateToken()
            // 存入到緩存中
            uni.setStorageSync('accessToken', token)
            // 設置定時任務,每隔7000秒更新一次tonken
            setInterval(async () => {
                // 獲取新的token
                let token = await updateToken()
                // 存入到緩存中
                uni.setStorageSync('accessToken', token)
            }, 7000000);
            console.log('接口獲取的token');
            // 返回結果
            resolve(token)
        }
    })
}

請求微信地址的跨域問題

上面的代碼中可以看到請求地址是以 /weixin 開頭的,這是因為我們在前端直接請求 https://api.weixin.qq.com 會產生跨域問題,所以我配置了前端代理,配置方式如下:

首先在項目根目錄新建 vue.config.js 文件,編寫如下代碼

module.exports = {
    publicPath: "./",
    devServer: {
        disableHostCheck: true, //禁用主機檢查 
        proxy: {
            "/weixin": {
                target: "https://api.weixin.qq.com/",
                ws: true,
                secure: true, // 使用的是http協議則設置為false,https協議則設置為true
                changOrigin: true, //開啟代理
                pathRewrite: {
                    "^/weixin": "",
                },
            }
        },
    },
};

然后重啟項目,之后在發送請求時,用 /weixin 開頭去發送請求,則node會自動幫我們吧請求地址代理到 https://api.weixin.qq.com/ ,從而解決跨域問題

創建菜單

接口地址

POST(請使用https協議) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN

接口參數見官網文檔

下面代碼即可為測試號創建一個普通菜單

const ACCESS_TOKEN = uni.getStorageSync("accessToken");
const menuObj = {
    button: [
        {
            type: "view",
            name: "測試項目",
            url: "http://192.168.60.230:8080/",
        },
    ],
};
// 創建菜單
http.post(`/weixin/cgi-bin/menu/create?access_token=${ACCESS_TOKEN}`, menuObj).then((res) => {
    console.log(res, "創建菜單");
});

代碼執行后,我們掃描測試號的二維碼,即可看到配置的菜單。這里要保證我們的手機和電腦在同一個局域網下,通俗點就是連着同一個WiFi,這樣我們才能在手機端點擊菜單進入到我們的項目中

微信網頁授權

授權步驟

引導關注者開發授權頁面

我們可以讓用戶跳轉到授權頁面,如果用戶同意授權,頁面將跳轉至 redirect_uri/?code=CODE&state=STATE。

授權地址

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

參數說明

參數 是否必須 說明
appid 公眾號的唯一標識
redirect_uri 授權后重定向的回調鏈接地址, 請使用 urlEncode 對鏈接進行處理
response_type 返回類型,請填寫code
scope 應用授權作用域,snsapi_base (不彈出授權頁面,直接跳轉,只能獲取用戶openid),snsapi_userinfo (彈出授權頁面,可通過openid拿到昵稱、性別、所在地。並且, 即使在未關注的情況下,只要用戶授權,也能獲取其信息 )
state 重定向后會帶上state參數,開發者可以填寫a-zA-Z0-9的參數值,最多128字節
#wechat_redirect 無論直接打開還是做頁面302重定向時候,必須帶此參數

開始編碼

<view>
    <button type="info" @click="getUserInfo">獲取授權</button>
</view>
data() {
    return {
        homeUrl:"http://192.168.60.230:8080/",
    };
},
methods: {
    // 點擊授權按鈕
    getUserInfo() {
        // 獲取當前頁面地址作為回調地址,並且對地址進行urlEncode處理
        let local = encodeURIComponent(this.homeUrl);
        // 獲取公眾號appid
        let appid = "wx2188729b190d357d";
        // 跳轉到授權頁面
        window.location.href =
            "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +
            appid +
            "&redirect_uri=" +
            local +
            "&response_type=code&scope=snsapi_base&state=1#wechat_redirect";
    },
}

點擊按鈕跳轉到授權頁面,然后微信會將參數拼接到回調地址中,我們從地址中獲取code參數來獲取網頁授權的 access token

通過路徑上的code獲取網頁授權token

獲取token的接口地址

GET https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

首先我們封裝一個獲取路徑參數的方法

getUrlCode(name) {
    return (
        decodeURIComponent(
            (new RegExp("[?|&]" + name + "=" + "([^&;]+?)(&|#|;|$)").exec(
                location.href
            ) || [, ""])[1].replace(/\+/g, "%20")
        ) || null
    );
}

然后再添加一個根據code獲取token的方法,這里的APPIDAPPSECRET放在了data中,這里可以優化成寫一個配置文件,頁面可以從配置文件中獲取。

data() {
    return {
        APPID: "wx2188729b190d357d",
        APPSECRET: "d976b0e6262b829ba003e9a24032447c",
    };
},
// 根據code獲取網站授權token
getTokenFormCode(code) {
    http.get(
        `/weixin/sns/oauth2/access_tokenappid=${this.APPID}&secret=${this.APPSECRET}&code=${code}&grant_type=authorization_code`
    ).then((res) => {
        console.log(res.data.access_token,'根據code獲取網站授權token');
        console.log(res.data.openid,'獲取到的用戶openid'); 
    });
},

然后在 onLoad中先判斷路徑上能否獲取到 code 值,如果獲取到后再調用接口去獲取網頁授權token

onLoad() {
    // 判斷是否有code
    let weixinCode = this.getUrlCode("code");
    // 當獲取到code后再調用獲取token的方法
    weixinCode && this.getTokenFormCode(weixinCode);
},

拉取用戶信息

注意:這個方法需 scopesnsapi_userinfo

接口地址

GET https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

編寫方法

// 根據網頁授權token和openid獲取用戶基礎信息
getAuthorizationInfo(token, openid) {
    http.get(`/weixin/sns/userinfo?access_token=${token}&openid=${openid}&lang=zh_CN`).then((res) => {
        console.log(res, "用戶基礎信息");
    });
},

改寫 getTokenFormCode 方法,接口調用成功后傳遞 tokenopenidgetAuthorizationInfo 方法來獲取用戶基本信息

// 根據code獲取網站授權token
getTokenFormCode(code) {
    http.get(
        `/weixin/sns/oauth2/access_tokenappid=${this.APPID}&secret=${this.APPSECRET}&code=${code}&grant_type=authorization_code`
    ).then((res) => {
        const { access_token, openid } = res.data;
        this.getAuthorizationInfo(access_token, openid); 
    });
},

接口返回結果

根據接口數據展示頭像和昵稱

getAuthorizationInfo 方法中添加如下代碼,保存用戶信息

// 根據code獲取網站授權token
getAuthorizationInfo(token, openid) {
    http.get(`/weixin/sns/userinfo?access_token=${token}&openid=${openid}&lang=zh_CN`).then((res) => {
        // 解構賦值
        const { headimgurl, nickname } = res.data;
        this.userInfo = {
            // 用戶頭像
            headimgurl: headimgurl,
            // 用戶微信昵稱
            nickname: nickname,
        };
    });
},

在頁面上展示用戶信息

<view class="userInfo">
    <view>
        <image :src="userInfo.headimgurl"></image>
    </view>
    <view>{{ userInfo.nickname }}</view>
</view>

效果展示


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM