Vue+abp微信掃碼登錄的實(shí)現(xiàn)代碼示例
最近系統(tǒng)中要使用微信掃碼登錄,根據(jù)微信官方文檔和網(wǎng)絡(luò)搜索相關(guān)文獻(xiàn)實(shí)現(xiàn)了。分享給需要的人,也作為自己的一個(gè)筆記。后端系統(tǒng)是基于ABP的,所以部分代碼直接使用了abp的接口,直接拷貝代碼編譯不通過(guò)。
注冊(cè)微信開(kāi)放平臺(tái)賬號(hào)#
在微信開(kāi)放平臺(tái)注冊(cè),注意是開(kāi)放平臺(tái)不是公眾平臺(tái),這里需要300元,然后申請(qǐng)網(wǎng)站應(yīng)用。審核通過(guò)后獲取到AppID和AppSecret以及登記的網(wǎng)站url。只有此url下的地址微信掃碼后才能回調(diào)。
具體申請(qǐng)條件見(jiàn)官方文檔。
生成登錄二維碼#
在vue登錄頁(yè)面嵌入登錄二維碼,根據(jù)官方文檔,在頁(yè)面中放入一個(gè)div元素,二維碼就放在此元素中,注意var obj = new WxLogin必須放在mounted方法中執(zhí)行,此時(shí)vue才會(huì)把dom元素初始化掛載到dom樹(shù),可以參見(jiàn)vue官方文檔生命周期介紹。
<template> <div id="login" class="login"></div> </template> <script> export default { name: "WXLogin", data: function() { return {}; }, mounted() { this.wechatHandleClick(); document.getElementsByTagName("iframe")[0].height="320"; document.getElementsByTagName("iframe")[0].style.marginLeft="30px"; }, methods: { wechatHandleClick() { let ba64Css = "css代碼base64編碼";// 微信需要https的樣式路徑,這里將樣式內(nèi)容加密base64,可以避免使用https,如果你的網(wǎng)站是https的可以直接使用安官方文檔使用css文件路徑 const appid = "你第一步申請(qǐng)的Appid"; const redirect_uri = encodeURIComponent("http://*/#/login"); var obj = new WxLogin({ id: "login", //div的id appid: appid, scope: "snsapi_login",//固定內(nèi)容 redirect_uri: redirect_uri, //回調(diào)地址 // href: "http://*/static/UserCss/WeChart.css" //自定義樣式鏈接,第三方可根據(jù)實(shí)際需求覆蓋默認(rèn)樣式。 href: "data:text/css;base64," + ba64Css // state: "", //參數(shù),可帶可不帶 // style: "", //樣式 提供"black"、"white"可選,默認(rèn)為黑色文字描述 }); } } }; </script>
注冊(cè)回調(diào)事件#
用戶掃碼后微信會(huì)回調(diào)訪問(wèn)前一步提供的redirect_uri,這里要監(jiān)控微信回調(diào),并用微信返回的code請(qǐng)求后端,在后端再去訪問(wèn)微信服務(wù)器獲取token及用戶openID
在回調(diào)頁(yè)面中監(jiān)控路由改變事件以監(jiān)控微信回調(diào)(因?yàn)槲业亩S碼和回調(diào)在同一個(gè)路由頁(yè)面),如果有其他更好的方法請(qǐng)告訴我。
@Watch("$route") async RouteChange(newVal, oldVal) { await this.weixinRedirect(); } // 請(qǐng)求微信后臺(tái) async weixinRedirect() { let code = this.$route.query.code; let state = this.$route.query.state; if (code) { let wxTo = { code, state }; //請(qǐng)求后臺(tái) this.$http("*/WeixinRedirect",data:wxTo).then((token)=>{ //登錄成功,把token寫(xiě)入cookie //跳轉(zhuǎn)到主頁(yè) this.$router.replace({ path: "/", replace: true }); }).catch(error => { //保持當(dāng)前頁(yè)面 this.$router.replace({ path: "/login", replace: true }); }); } } }
后端接收code請(qǐng)求token#
在appsettings.json中配置AppId和AppSecret
[HttpPost] public async Task<AuthenticateResultModel> WeixinRedirect(string code, string state) { if (code.IsNullOrEmpty()) { throw new UserFriendlyException("微信授權(quán)失敗,請(qǐng)重新授權(quán)"); } var appid = configuration["Authentication:Wechat:AppId"]; var secret = configuration["Authentication:Wechat:AppSecret"]; var url = $"https://api.weixin.qq.com/sns/oauth2/access_token?appid={appid}&secret={secret}&code=[code]&grant_type=authorization_code"; var httpClient = httpClientFactory.CreateClient(); httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"); httpClient.Timeout = TimeSpan.FromMinutes(3); var resstr = await httpClient.GetStringAsync(url); try{ //如果微信授權(quán)返回失敗這里序列化不成功 var res = JsonSerializationHelper.DeserializeWithType<WeiXinAccess_tokenResponse>(resstr); }catch (Exception e) { throw new UserFriendlyException("獲取微信access_token失敗"); } if (res == null || res.openid.IsNullOrEmpty()) { throw new UserFriendlyException("獲取微信access_token失敗"); } var userId = //根據(jù)openID獲取用戶id,我們系統(tǒng)要求用戶提前把微信和用戶關(guān)聯(lián)綁定,所以這里可以根據(jù)微信用戶的openID獲取到戶農(nóng)戶id; //使用用戶直接登錄 if (!userId.IsNullOrEmpty()&&long.TryParse(userId, out long id)) { var user = await _userManager.GetUserByIdAsync(id); var loginResult = await _logInManager.LoginByUser(user); string accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity)); return new AuthenticateResultModel { AccessToken = accessToken, EncryptedAccessToken = GetEncrpyedAccessToken(accessToken), ExpireInSeconds = (int)_tokenConfiguration.Expiration.TotalSeconds, UserId = loginResult.User.Id }; } throw new UserFriendlyException("微信尚未綁定賬號(hào),請(qǐng)使用賬號(hào)登錄后綁定微信。"); }
WeiXinAccess_tokenResponse類型
public class WeiXinAccess_tokenResponse { public string access_token { get; set; } public int expires_in { get; set; } public string refresh_token { get; set; } public string openid { get; set; } public string scope { get; set; } public string unionid { get; set; } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:JS實(shí)現(xiàn)電商商品展示放大鏡特效
欄 目:JavaScript
本文標(biāo)題:Vue+abp微信掃碼登錄的實(shí)現(xiàn)代碼示例
本文地址:http://mengdiqiu.com.cn/a1/JavaScript/9279.html
您可能感興趣的文章
- 04-02微信挑一挑java代碼 微信挑一挑java代碼怎么做
- 01-10微信小程序批量上傳圖片到七牛(推薦)
- 01-10微信小程序跨頁(yè)面數(shù)據(jù)傳遞事件響應(yīng)實(shí)現(xiàn)過(guò)程解析
- 01-10微信小程序按順序同步執(zhí)行的兩種方式
- 01-10微信小程序?qū)崿F(xiàn)簽字功能
- 01-10java遇到微信小程序 "支付驗(yàn)證簽名失敗" 問(wèn)題解決
- 01-10微信小程序如何獲取地址
- 01-10微信小程序自定義模態(tài)彈窗組件詳解
- 01-10通過(guò)微信公眾平臺(tái)獲取公眾號(hào)文章的方法示例
- 01-10微信小程序停止其他視頻 當(dāng)前視頻的實(shí)例代碼


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02javascript點(diǎn)線,點(diǎn)線的代碼
- 04-02javascript潛力,javascript強(qiáng)大嗎
- 04-02javascript替換字符串,js字符串的替換
- 04-02javascript移出,js 移入移出
- 04-02包含javascript舍的詞條
- 04-02javascript并行,深入理解并行編程 豆瓣
- 04-02javascript匿名,js匿名方法
- 04-02javascript警報(bào),JavaScript警告
- 04-02javascript遮蓋,JavaScript遮蓋PC端頁(yè)面
- 04-02javascript前身,javascript的前身
隨機(jī)閱讀
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置