运维开发网

PC 端微信扫码注册和登录实例

运维开发网 https://www.qedev.com 2020-04-16 13:36 出处:网络 作者: Cboyce
PC 端微信扫码注册和登录 一、前言 先声明一下,本文所注重点为实现思路,代码及数据库设计主要为了展现思路,如果对代码效率有着苛刻要求的项目切勿照搬。

PC 端微信扫码注册和登录

一、前言

先声明一下,本文所注重点为实现思路,代码及数据库设计主要为了展现思路,如果对代码效率有着苛刻要求的项目切勿照搬。

相信做过微信开发的人授权这块都没少做过,但是一般来说我们更多的是为移动端的网站做授权,确切来说是在微信端下做的一个授权。今天遇到的一个问题是,项目支持微信端以及 PC 端,并且开放注册。要求做到无论在 PC 端注册或者是在微信端注册之后都可以在另外一个端进行登录。也就是说无论 PC 或是微信必须做到"你就是你"(通过某种方式关联)。

二、寻找解决方案

按传统的方式来思考,微信端完全可以通过授权进行注册,但是PC端呢,传统的方式无非就是填填手机号码啊,或者 Email 等等。如果采用这种方式注册,会产生下面这的问题

1.我先在微信端授权注册,那么如果我要登录PC端还是得进行注册。

对此解决方案可以为:微信授权注册后“强制”要求用户必须填写基本信息,如手机号、Email 。这样我们可以通过某种方式为用户生成PC端登录的账号密码.例如以用户的 nickname 为账号,手机号码为密码,等等方式。

弊端:用户体验不好,再者有安全隐患。毕竟你的微信昵称, Email 或者手机号码都是暴露的。

2.如果我先在 PC 端注册,我在微信授权的时候怎样关联移动端, 当然,凡是问题总会有解决方案的。思路如下:

    方案一:当用户在 PC 端注册后,“强制” 用户必须填写微信昵称。以此作为微信授权时的关联条件。但是很遗憾,微信昵称可以改,不是唯一的怎么可以用来做关联?方案一阵亡。

    方案二:在微信端授权后,以及在 PC 端注册后“强制”要求用户填写手机号码以此为关联。这样衍生出一个问题,必须确保用户手机的真实信,没问题。这个可以通过手机验证码来实现(Email也是一样)。但是不妨假设一下有下面这种情况,如果我有两个手机号码,PC 端注册时填一个,微信注册时填另一个。关联的了吗?答案是很遗憾。再者,我在PC 端注册后我就是不填(笔者把强制打上双引号的原因),然后我用微信端授权登录一下。好吧,此时将会有两条数据等着你想办法去关联,典型的开发者自挖坑。这种方式某种程度上行得通,但是严谨程度上是开发者无法接受的。

三、回归原点的解决方案

分析:既然方案上述方案都有问题,我们先把它们都抛到一边。整理一下思路,让我们回到问题的根本。关联的问题,要的是一个唯一标识。唯一标识正如我们的身份证号码,我们办理信用卡的时候身份证是必须的,实名制下购买号码卡,身份证是必须的。假设我们是这系统管理员,那么我完全可以通过你的身份证号码查出你手机号码,银行卡号码。

PC 端微信扫码注册和登录实例

有了上面的思路之后,我们需要做的就是找到一个唯一标识来作为关联.微信上有个重要的角色 openid。 它跟我们上面提到的身份证号码有这共同的作用,微信账号对某一公众号的唯一标识。

PC 端微信扫码注册和登录实例

微信端的授权拿到 openid 做过微信开发的人都应该没有问题。问题是怎样来实现 PC 端 在注册或者登陆的时候拿到 openid。笔者的实现思路如下。PC 端注册,或者登陆时显示一个二维码引导用户使用微信扫码,使其跳转到授权页面。这一步有一个最为关键的细节,二维码请带上一个唯一的授权码(authCode)。试想一下如果用户授权后我们能把 openid 以及 authCode 写入到数据库。那么我们就可以在 PC 端通过某个 API 获取 authCode 所关联的这个 openid。如果我们做到这点我们就可以知道当前是谁在 PC 端进行扫码注册或登录(没注册的注册,有注册的直接登录)。 是不是突然觉得 so easy. 如果觉得文字比较抽象,请看下面图示

PC 端微信扫码登录流程

PC 端微信扫码注册和登录实例

核心代码

搞清楚了思路和流程接下来我们直接上代码啦.开发思路是共通的,开发语言就请各显神通啦。

说明:下面代码以 C# 语言为例,采用 MVC + EF (注:uuid 等价于我们上述的 authCode)

扫码登录页后台代码

public ActionResult Login()
{
  //如果已登录,直接跳转到首页
  if (User.Identity.IsAuthenticated)
    return RedirectToAction("Index", "Home");

  string url = Request.Url.Host;
  string uuid = Guid.NewGuid().ToString();
  ViewBag.url = "http://" + url + "/home/loginfor?uuid=" + uuid;//构造授权链接
  ViewBag.uuid = uuid;//保存 uuid
  return View();
}

生成二维码采用插件 jquery.qrcode.js,想详细了解的朋友请移步 Github。 这里需要注意的一点是,该插件可以指定二维码的生成方式,canvas 或者 table 请需要支持 IE 的朋友指定使用 table 生成

代码如下:

jQuery('#qrcode').qrcode({
  render  : "table",
  text  : "http://baidu.com"
});

回归正题,登录页面的主要代码如下

<!--生成二维码的容器 div-->
<div id="qrcode-container">
</div>

<script src="~/Plugins/Jquery/jquery-1.9.1.min.js"></script>
<script src="~/Plugins/jquery-qrcode/jquery.qrcode.min.js"></script>
<script>
  jQuery(function () {
    //生成二维码
    jQuery('#qrcode-container').qrcode("@ViewBag.url");

    //轮询判断用户是否授权
    var interval = setInterval(function () {
      $.post("@Url.Action("UserLogin","Home")", { "uuid": "@ViewBag.uuid" }, function (data, status) {
        if ("success" == status) {
          //用户成功授权=>跳转
          if ("success" == data) {
            window.location.href = '@Url.Action("Index", "Home")';
            clearInterval(interval);
          }
        }
      });
    }, 200);
  })
</script>

轮询判断用户是否授权 API 代码

public string UserLogin(string uuid)
{
  //验证参数是否合法
  if (string.IsNullOrEmpty(uuid))
    return "param_error";

  WX_UserRecord user = db.WX_UserRecord.Where(u => u.uuId == uuid).FirstOrDefault();
  if (user == null)
    return "not_authcode";

  //写入cookie
  FormsAuthentication.SetAuthCookie(user.OpenId, false);

  //清空uuid
  user.uuId = null;
  db.SaveChanges();

  return "success";
} 

微信端授权 Action

public ActionResult Loginfor(string uuid)
{

  #region 获取基本信息 - snsapi_userinfo

  /*
   * 创建微信通用类 - 这里代码比较复杂不在这里贴出
   * 迟点我会将整个 Demo 稍微整理放上 Github
  */
  WechatUserContext wxcontext = new WechatUserContext(System.Web.HttpContext.Current, uuid);

  //使用微信通用类获取用户基本信息
  wxcontext.GetUserInfo();

  if (!string.IsNullOrEmpty(wxcontext.openid))
  {
    uuid = Request["state"];
    //判断数据库是否存在
    WX_UserRecord user = db.WX_UserRecord.Where(u => u.OpenId == wxcontext.openid).FirstOrDefault();
    if (null == user)
    {
      user = new WX_UserRecord();
      user.OpenId = wxcontext.openid;
      user.City = wxcontext.city;
      user.Country = wxcontext.country;
      user.CreateTime = DateTime.Now;
      user.HeadImgUrl = wxcontext.headimgurl;
      user.Nickname = wxcontext.nickname;
      user.Province = wxcontext.province;
      user.Sex = wxcontext.sex;
      user.Unionid = wxcontext.unionid;          
      user.uuId = uuid;
      db.WX_UserRecord.Add(user);
    }
    user.uuId = uuid;
    db.SaveChanges();
  }
  #endregion

  return View();
} 

最后附上数据库表设计

没什么特殊的,就是微信返回的各个参数加多一个我们自定义的 uuId

PC 端微信扫码注册和登录实例

微信参数说明 详情请见 微信开发者文档

PC 端微信扫码注册和登录实例

运行效果

1.扫码登录页面

PC 端微信扫码注册和登录实例

2.请求用户授权

PC 端微信扫码注册和登录实例

3.用户确认授权

PC 端微信扫码注册和登录实例

4.PC 端登录完成

PC 端微信扫码注册和登录实例

文章难免有不足之处,还请海涵。如有发现错误还望留言指出,笔者感激不尽! 微信扫码注册登录 Demo 待笔者整理后放上 Github 希望帮到更多的朋友,请有需要的朋友留意该文更新。

以上就是PC 端微信扫码注册和登录 的实例,有需要的朋友可以参考下,谢谢大家对本站的支持!

0

精彩评论

暂无评论...
验证码 换一张
取 消