Web 网站利用小程序扫码登录

小占时光 2024-07-19 15:27:44 2098


          以前做了一个小程序,但好久没用了,前段时间做网站登录的时候,写了一个文章 ➤ 系统支付宝、QQ、微博、Github三方登录接入 还剩微信登录没做,就又手痒了,加了一个微信登录。当然不是微信认证的那种登录,微信认证对于这种博客网站是没有必要的。所以就使用曲线救国计划,使用小程序登录。

一、前期准备

    (1)申请一个微信小程序,这里需要准备一个没有用过的邮箱。

    (2)学习小程序开发,对于前端开发来说应该不难,会使用css,js,html这些就可以看懂了。

    (3)后端开发,我使用C#开发的,所以示例代码可能就是用C#代码,java原理也一样。

    (4)小程序认证,这个认证要30元,可以选择不认证(如果只是简单实践就不需要认证了),不认证在微信里面就搜索不出你的小程序,哎,以前可不是这样的。

原理

         使用微信小程序二维码,扫码时跳转小程序获得用户的授权码,使用授权码,查询openId,有了openId就可以获得用户信息,登录网站,为了更好理解画了一个图,虽然画的不好但方便理解吧。

         打开网站登录页面的电脑很多,扫码后要登录哪一个呢。这就必须能识别当前登录页面显示的二维码是哪一个。微信小程序二维码(不限制的小程序码)获取的接口

➤ https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getUnlimitedQRCode.html

这个接口可以带一个参数 scene,使用guid,去掉“-”,刚好32位。

最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)

      获取小程二维码时还需要指定跳转到小程序的哪个页面(必须已经提交过的代码里存在此页面,如果不存在会接口报异常,可以建一个空页面先提交审核后面慢慢实现,不然又要等着),可以单独写一个登录页面,模仿微信授权登录页面。下面就是本站登录扫码登录时的页面(为啥叫小占时光呢?因为取了很多其他名字备案都不能通过,气死个人)。

 

二、代码实现

        实现的话分为三个部分,web前端页面,web服务端,微信小程序。

 

web前端页面

       前端页面实现的话,比较简单,显示获取获取二维码,显示出来。后面就是不断的请求服务端,看看登录了没。由于使用的是后端渲染,获取到图片就直接放到img标签中了。其他就是循环请求服务端了,如果已经登录则直接跳转到首页。

var url = $('#url').val();
var timer = setInterval(function() {
abp.ajax({
        type: 'get',
        url: url,
        success: function(data) {
            if (data.status == 2) {
              window.location.href = "/";
             }
         },
     });
},500);

登录页面效果

 

web服务端

       服务端第一个事情就是 获取二维码 登录页面每次都会获取新的二维码,更具文档要求,添加参数请求即可,这里的scene就是自己给的唯一参数了 ,scene是唯一标识,需要保存在服务端,由于不是长期数据,服务端我使用缓存将其保存起来,前端来请求时就从缓存中获取。获取小程序二维码时,page 一定是要存在的,如果提示异常,记得先检查页面是否已经提交了,没有就先把页面提交上去

获取二维码的地址:➤ https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getUnlimitedQRCode.html

下面是参考代码,代码没有考虑错误的情况,可以按自己需求添加判断

public async Task<byte[]?> GetUnlimitedQRCode(string env_version, string scene, string page)
{
    var token = await GetAccessTokenAsync();
    var url = string.Format(MiniprogramApi.GetUnlimitedQRCode_Url, token.AccessTokenStr);

    var client = httpClientFactory.CreateClient(WeChatConsts.HttpClientName);

    ///请求消息
    var requestMessage = new HttpRequestMessage(HttpMethod.Post, url);

    var paras = JsonConvert.SerializeObject(new
    {
        page = page,
        scene = scene,
        check_path = true,
        env_version = env_version
    });

    // 请求的form内容
    var postContent = new StringContent(paras);

    requestMessage.Content = postContent;

    var respons = await client.SendAsync(requestMessage);
    var result = await respons.Content.ReadAsStringAsync();

    var qrCodeBytes = await respons.Content.ReadAsByteArrayAsync();
    return qrCodeBytes;
}

    第二件事就添加一个api接口,让小程序可以将授权码传过来,有了授权码,就可以得到openid,可以获取用户相关信息,但我只要了openId,因为openid就可以作为唯一标识,其他用户信息也没必要。代码只展示了实现逻辑具体细节自己现实吧:

  [HttpGet]
  [Route("openid")]
  public async Task<string> GetMiniUserOpenId(string code, string scene = null)
  {
     
      if (!string.IsNullOrEmpty(scene))
      {
          // code,是授权码,scene 是缓存中此处登录扫码的唯一id
          var openId = await miniAppService.GetOpenIdAsync(code, scene);

          if (string.IsNullOrEmpty(openId))
          {
              return null;
          }

          // 第三方登录
          var userId = await thirdPartyServices.GetUserAsync(ThirdPartyProvider.WinXin, openId);

          // 得到openid 同时登录系统,放回是带上一个状态判断是否登录成功
          var scanLogin = _cache.Get(scene);
          if (scanLogin != null)
          {
              scanLogin.Status = 2;
              scanLogin.UserId = userId;
              _cache.Set(scene, scanLogin);
          }
          else
          {
              // 扫码已经过期,请重新扫码
              return null;
          }
          return openId;
      }

      return null;
  }

同时附上获取openid和获取token的文档地址,获取openid前需要现获取token

获取token 地址:➤ https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html
获取openId的地址:➤ https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html

微信小程序

     微信小程序实现,就比较简单了,获取授权码——> 请求服务端获取openId,如果需要用户其他信息,则根据用户openid就可以获取到,但这样在小程序发布时就需要添加 “隐私条例“,用户信息我不需要,所以只用了openId做唯一标识。服务端获取到openid后,就直接修改了登录状态,web页面来查询时,已经是登录它就跳转首页,小程序同样跳转收即可(也可以显示登录成功字样)。下面就是示例代码了。

  login()
  {
    let self =this;
    wx.login({
      success: (res) => {
        if (res.code) {
          console.log("Login code: ", res.code);
          api.getOpenId(res.code,self.data.scene)
          .then((res)=>{
              console.log('登录成功,openId:' + res)
              wx.switchTab({url:"/pages/index/index"});
          });
        } else {
          console.log('登录失败!' + res.errMsg);
        }
      }
    });
  }

 

 

最后一次修改 : 2025/1/23 上午11:33:03

优秀
123
分享
123
奶茶
123
文章版权声明:版权归原作者(小占时光)所有。未经明确书面许可,严禁任何个人或组织以任何形式进行商业性或非商业性的使用、转载或抄袭。
评论