1. 程式人生 > 程式設計 >Vue+abp微信掃碼登入的實現程式碼示例

Vue+abp微信掃碼登入的實現程式碼示例

最近系統中要使用微信掃碼登入,根據微信官方文件和網路搜尋相關文獻實現了。分享給需要的人,也作為自己的一個筆記。後端系統是基於ABP的,所以部分程式碼直接使用了abp的介面,直接拷貝程式碼編譯不通過。

註冊微信開放平臺賬號#

在微信開放平臺註冊,注意是開放平臺不是公眾平臺,這裡需要300元,然後申請網站應用。稽核通過後獲取到AppID和AppSecret以及登記的網站url。只有此url下的地址微信掃碼後才能回撥。

具體申請條件見官方文件。

生成登入二維碼#

在vue登入頁面嵌入登入二維碼,根據官方文件,在頁面中放入一個div元素,二維碼就放在此元素中,注意var obj = new WxLogin必須放在mounted方法中執行,此時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的樣式路徑,這裡將樣式內容加密base64,可以避免使用https,如果你的網站是https的可以直接使用安官方文件使用css檔案路徑
   const appid = "你第一步申請的Appid";
   const redirect_uri = encodeURIComponent("http://*/#/login");
   var obj = new WxLogin({
    id: "login",//div的id
    appid: appid,scope: "snsapi_login",//固定內容
    redirect_uri: redirect_uri,//回撥地址
    // href: "http://*/static/UserCss/WeChart.css" //自定義樣式連結,第三方可根據實際需求覆蓋預設樣式。    
    href: "data:text/css;base64," + ba64Css
    // state: "",//引數,可帶可不帶
    // style: "",//樣式 提供"black"、"white"可選,預設為黑色文字描述
   });
  }
 }
};
</script>

註冊回撥事件#

使用者掃碼後微信會回撥訪問前一步提供的redirect_uri,這裡要監控微信回撥,並用微信返回的code請求後端,在後端再去訪問微信伺服器獲取token及使用者openID

在回撥頁面中監控路由改變事件以監控微信回撥(因為我的二維碼和回撥在同一個路由頁面),如果有其他更好的方法請告訴我。

 @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
     //跳轉到主頁
      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("微信授權失敗,請重新授權");
  }
  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{
    //如果微信授權返回失敗這裡序列化不成功
   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 = //根據openID獲取使用者id,我們系統要求使用者提前把微信和使用者關聯繫結,所以這裡可以根據微信使用者的openID獲取到戶農戶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; }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。