# 公众号 H5 独立登录

本文档为[公众号 H5 访问](h5)的扩展文档，主要讲解在项目页面非常多的情况下，如何拆分初始化和登录过程，使用独立登录页提高效率。

**需要注意：由于云托管 SDK 使用 `localStorage` 记录登录关键信息，所以目前不支持不同域的页面分拆，也就是说业务页面和登录页面必须在一个域中**

## 使用步骤

首先，在网页中引入如下 3 个 JS 文件

```bash
# 微信公众号SDK，用于使用前端公众号接口，如果不需要可以不引入
https://res.wx.qq.com/open/js/jweixin-1.6.0.js

# 微信云服务SDK，用于调用微信云服务资源
https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/cloud.js

# 封装的登录授权模块，用于一步完成授权登录步骤
https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/mplogin2.min.js
```

构建一个登录页，确定路径，在这里是 `login.html`，和业务页面平级

登录页面可以加入一些动画，展示登录中的形态

``` html
<!DOCTYPE html>

<head>
  <title>登录页面</title>
  <meta charset="UTF-8">
  <script src="https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/mplogin2.min.js"></script>
  <script src="https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/cloud.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
</head>

<body>登录中</body>
<script>
  window.onload = function () {
    window.mplogin2.doLogin({
      appid: 'wxaa01testenvid99',                   // 必填，公众号appid，将以此appid名义进行请求
      scope: 'snsapi_userinfo',                     // 必填，登录方式：snsapi_userinfo、snsapi_base// 必填，登录方式：snsapi_userinfo、snsapi_base
      // noback: true,                              // 选填，登录完不直接返回业务页面，执行自定义附加操作
      // redirect: window.location.href             // 跳转的页面，默认是当前页面，如果你有自定义登录成功页，可以联动设置 
    }).then(res => {
      // noback为true时，将不会返回业务页面，执行到这里
      // 此时需要自行控制跳转回业务页面
      console.log(res)
    })
  }
</script>

</html>
```

在业务页面中，引入关键 JS，发起 check 过程，以下是示例，需自行理解后并入自身业务中

其中，`loginUrl` 参数中，登录页的路径需要和真实的登录页保持一致，保证能正确路由

``` html
<!DOCTYPE html>

<head>
  <title>业务页面</title>
  <meta charset="UTF-8">
  <script src="https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/mplogin2.min.js"></script>
  <script src="https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/cloud.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
</head>

<body>业务代码</body>
<script>
  window.onload = async function () {
    window.mplogin2.checkCloud({
      appid: 'wxaa01testenvid99',               // 必填，公众号appid，将以此appid名义进行请求
      resourceAppid: 'wxaa01testenvid99',       // 必填，如果是资源复用模式，需要填环境共享下资源方微信账号
      envid: 'prod-testenvid',                  // 必填，资源方微信云托管环境，如果传递此参数则会返回初始化的cloud操作对象
      loginUrl: './login.html',                      // 选填，如果指定登录页地址，未登录时直接发起跳转，需对应页面有设置联动
      // signature: window.location.href,       // 选填，如果需要微信SDK的API方法，则填写要使用的地址，会返回signature签名对象，envid参数不填则无效。
      // region: ''                             // 选填，环境的地域，可选ap-guangzhou、ap-beijing，不填默认为ap-shanghai
      // traceUser:false                        // 选填，默认true，是否在将用户访问记录到用户管理中，非上海地域请设置成false
    }).then(res => {
      if (res.login === true && res.cloud != null) {
        // 开始业务
        console.log('用于操作的CLOUD对象', res.cloud)
        console.log('微信用户信息', res.info)
      } else {
        // 登录不成功，或环境加载失败，需按照提示解决
        console.log(res.msg)
      }
    })
  }
</script>

</html>
```

如果你不想模块自行发起跳转登录，则不需要传 `loginUrl` 参数，此时需要自行实现跳转和回调细节，以下是实例。

``` html
<!DOCTYPE html>

<head>
  <title>业务页面</title>
  <meta charset="UTF-8">
  <script src="https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/mplogin2.min.js"></script>
  <script src="https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/cloud.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
</head>

<body>业务代码</body>
<script>
  window.onload = async function () {
    window.flag = false
    loadcloud()
  }
  // 在登录页没有传 noback:true ，使用自动回退时，安卓、PC会重新刷新页面，IOS不会刷新，所以这里主要用于IOS响应回传。
  document.addEventListener("visibilitychange", function () {
    if (!document.hidden && window.flag) { // 设置flag防止重复加载
      loadcloud()
    }
  })
  function loadcloud(){
    window.mplogin2.checkCloud({
      appid: 'wxaa01testenvid99',               // 必填，公众号appid，将以此appid名义进行请求
      resourceAppid: 'wxaa01testenvid99',       // 必填，如果是资源复用模式，需要填环境共享下资源方微信账号
      envid: 'prod-testenvid',                  // 必填，资源方微信云托管环境，如果传递此参数则会返回初始化的cloud操作对象
      // signature: window.location.href,       // 选填，如果需要微信SDK的API方法，则填写要使用的地址，会返回signature签名对象，envid参数不填则无效。
      // region: ''                             // 选填，环境的地域，可选ap-guangzhou、ap-beijing，不填默认为ap-shanghai
      // traceUser:false                        // 选填，默认true，是否在将用户访问记录到用户管理中，非上海地域请设置成false
    }).then(res => {
      if (res.login === true) {
        if (res.cloud != null) {
          // 开始业务
          window.flag = true
          console.log('用于操作的CLOUD对象', res.cloud)
          console.log('微信用户信息', res.info)
        } else {
          // 登录成功，但环境加载失败，需按照提示解决
          console.log(res.msg)
        }
      } else {
        // 没有登录，需跳转到登录页面
        // 以下方式可以适应IOS、安卓、PC平台的跳转和返回
        const a = document.createElement("a");
        a.href = './login.html' // 需要和登录页保持一致
        a.click()
      }
    })
  }
</script>

</html>
```

## 注意事项

1. `loadcloud` 返回的 `cloud` 对象可以存在全局中，在业务中重复使用。
2. `loadcloud` 返回的 `info` 为用户头像等信息，可以使用[此文档](/miniprogram/dev/server/API/cloudbase/others/api_getopendata.md)API 获取明文信息。
