Vue+abp微信掃碼登錄的實現(xiàn)代碼示例
最近系統(tǒng)中要使用微信掃碼登錄,根據(jù)微信官方文檔和網(wǎng)絡搜索相關文獻實現(xiàn)了。分享給需要的人,也作為自己的一個筆記。后端系統(tǒng)是基于ABP的,所以部分代碼直接使用了abp的接口,直接拷貝代碼編譯不通過。
注冊微信開放平臺賬號#
在微信開放平臺注冊,注意是開放平臺不是公眾平臺,這里需要300元,然后申請網(wǎng)站應用。審核通過后獲取到AppID和AppSecret以及登記的網(wǎng)站url。只有此url下的地址微信掃碼后才能回調(diào)。

具體申請條件見官方文檔。
生成登錄二維碼#
在vue登錄頁面嵌入登錄二維碼,根據(jù)官方文檔,在頁面中放入一個div元素,二維碼就放在此元素中,注意var obj = new WxLogin必須放在mounted方法中執(zhí)行,此時vue才會把dom元素初始化掛載到dom樹,可以參見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 = "你第一步申請的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ù)實際需求覆蓋默認樣式。
href: "data:text/css;base64," + ba64Css
// state: "", //參數(shù),可帶可不帶
// style: "", //樣式 提供"black"、"white"可選,默認為黑色文字描述
});
}
}
};
</script>
注冊回調(diào)事件#
用戶掃碼后微信會回調(diào)訪問前一步提供的redirect_uri,這里要監(jiān)控微信回調(diào),并用微信返回的code請求后端,在后端再去訪問微信服務器獲取token及用戶openID
在回調(diào)頁面中監(jiān)控路由改變事件以監(jiān)控微信回調(diào)(因為我的二維碼和回調(diào)在同一個路由頁面),如果有其他更好的方法請告訴我。
@Watch("$route")
async RouteChange(newVal, oldVal) {
await this.weixinRedirect();
}
// 請求微信后臺
async weixinRedirect() {
let code = this.$route.query.code;
let state = this.$route.query.state;
if (code) {
let wxTo = {
code,
state
};
//請求后臺
this.$http("*/WeixinRedirect",data:wxTo).then((token)=>{
//登錄成功,把token寫入cookie
//跳轉(zhuǎn)到主頁
this.$router.replace({ path: "/", replace: true });
}).catch(error => {
//保持當前頁面
this.$router.replace({ path: "/login", replace: true });
});
}
}
}
后端接收code請求token#
在appsettings.json中配置AppId和AppSecret

[HttpPost]
public async Task<AuthenticateResultModel> WeixinRedirect(string code, string state)
{
if (code.IsNullOrEmpty())
{
throw new UserFriendlyException("微信授權(quán)失敗,請重新授權(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)要求用戶提前把微信和用戶關聯(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("微信尚未綁定賬號,請使用賬號登錄后綁定微信。");
}
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; }
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
使用this.$router.go(-1)遇到的一些問題及解決
這篇文章主要介紹了使用this.$router.go(-1)遇到的一些問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
Vite3 Svelte3構(gòu)建Web應用報錯process is not def
這篇文章主要介紹了Vite3 Svelte3構(gòu)建Web應用報錯:'process is not defined'解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06
Vue Element UI + OSS實現(xiàn)上傳文件功能
這篇文章主要為大家詳細介紹了Vue Element UI + OSS實現(xiàn)上傳文件功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-07-07

