# 扫码登录第三方网站

使用知音楼客户端扫码并确认登录您的 web 系统,在您的系统内获得正在访问用户的知音楼身份,而用户无需输入账户密码。

注意:此功能与企业自建应用/第三方企业应用无关,只能用扫码登录打开第三方网站,并且不是知音楼内的应用免登,此流程只能做到获取到用户身份(无手机号和企业相关信息)。

# 获取 appId 及 appSecret

联系知音楼的产品冯照鹏老师(fengzhaopeng@tal.com;工号:098003),创建用于免登过程中验证身份的 appId 及 appSecret。

需提交字段 是否必填 说明
名称 必填 授权应用的名称
描述 必填 应用使用的场景
授权页面 LOGO 地址 必填 这个会显示在授权页面的中间页中,以 http 或 https 开头
回调域名 必填 应用回调的 URL,以 http 或 https 开头。需和本文“构造扫码登录页面”填写的 redirect_uri 域名保持一致,否则会提示无权限访问

# 构造扫码登录页面

Web 系统可以通过以下方式实现知音楼扫码登录。

# 支持网站将知音楼登录二维码内嵌到自己页面中

用户使用知音楼扫码登录后 JS 会将 loginTmpCode 返回给网站。JS 知音楼登录主要用途:网站希望用户在网站内就能完成登录,无需跳转到知音楼域下登录后再返回,提升知音楼登录的流畅性与成功率。

网站内嵌二维码知音楼登录 JS 实现办法:

步骤 1:安装

yarn add yach.open.yylogin

步骤 2:使用方式

浏览器使用:

<!-- 引入 -->
<script src="node_modules/yach.open.yylogin/lib/yyLogin.browser.js"></script>
<!-- 使用 -->
window.yyLogin(options);

npm使用:

// 引入
import yyLogin from "yach.open.yylogin";
// 使用
yyLogin(options);

步骤 3:在需要使用知音楼登录的地方实例以下 JS 对象

/*
 * 解释一下goto参数,参考以下例子:
 * var url = encodeURIComponent('http://localhost.me/index.php?a=1&b=2');
 * var goto = encodeURIComponent('https://yach-oapi.zhiyinlou.com/connect/oauth2/sns_authorize?appid=appid&response_type=code&scope=snsapi_login&state=STATE&redirect_uri='+url)
 */
const obj = yyLogin({
  id: "login_container", //这里需要你在自己的页面定义一个HTML标签并设置id,例如<div id="login_container"></div>或<span id="login_container"></span>
  goto: "", //请参考注释里的方式
  style: "border:none;background-color:#FFFFFF;",
  width: "365px",
  height: "400px",
});

参数说明:

参数 必填 说明
goto goto 参数结构:https://yach-oapi.zhiyinlou.com/connect/oauth2/sns_authorize?appid=APPID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=REDIRECT_URI&quick_sign=QUICK_SIGN,并且要将goto参数urlencode编码
style 渲染二维码的区域的样式,可以自定义去除背景颜色和边框
width 表示显示二维码的区域的宽 二维码大小是固定的 210px*210px
height 表示显示二维码的区域的高

# 注意:goto 参数中的 quick_sign 为头像快捷登录的签名,通过获取快捷登录签名

# 注意:如果在头像上方有红色提示,需要点击头像下方刷新按钮。

您可以通过以下代码获取这个 refreshUrl(获取到 refreshUrl,来判断重新加载页面):

var handleMessage = function (event) {
  var origin = event.origin;
  console.log("origin", event.origin);
  if (origin == "https://yach-work.zhiyinlou.com") {
    var refreshUrl = event.data;
    //获取到refreshUrl,来判断重新加载页面
    console.log("refreshUrl:", refreshUrl);
  }
};
if (typeof window.addEventListener != "undefined") {
  window.addEventListener("message", handleMessage, false);
} else if (typeof window.attachEvent != "undefined") {
  window.attachEvent("onmessage", handleMessage);
}

您引入的 js 会在获取用户扫描之后将获取的 loginTmpCode 通过 window.parent.postMessage(loginTmpCode,'*');返回给您的网站。

您可以通过以下代码获取这个 loginTmpCode:

var handleMessage = function (event) {
  var origin = event.origin;
  console.log("origin", event.origin);
  if (origin == "https://yach-work.zhiyinlou.com") {
    //判断是否来自yyLogin扫码事件。
    var loginTmpCode = event.data;
    //获取到loginTmpCode后就可以在这里构造跳转链接进行跳转了

    console.log("loginTmpCode", loginTmpCode);
  }
};
if (typeof window.addEventListener != "undefined") {
  window.addEventListener("message", handleMessage, false);
} else if (typeof window.attachEvent != "undefined") {
  window.attachEvent("onmessage", handleMessage);
}

通过 JS 获取到 loginTmpCode 后,需要由你构造并跳转到如下链接,参见通过用户授权码获取临时授权码

https://yach-oapi.zhiyinlou.com/connect/oauth2/sns_authorize?appid=APPID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=REDIRECT_URI&loginTmpCode=loginTmpCode

此链接处理成功后,会 302 跳转到 goto 参数指定的 redirect_uri,并向 url 参数中追加临时授权码 code 参数。

参数 是否必填 说明
appid 必填 扫码登录应用 appid
redirect_uri 必填 重定向地址(需要将 JS goto 参数整体 urlencode 编码,不要单独对 redirect_uri 编码),该地址使用域名需配置为 appId 对应的回调域名,回调域名是在获取 appId 及 appSecret 时填写
state 必填 用于防止重放攻击,开发者可以根据此信息来判断 redirect_uri 只能执行一次来避免重放攻击
response_type 必填 固定为 code
scope 必填 固定为 snsapi_login
loginTmpCode 必填 通过 js 获取到的 loginTmpCode

# 通过用户授权码获取临时授权码

# host: https://yach-oapi.zhiyinlou.com  正式环境

# host: https://yach-oapi-test.zhiyinlou.com  测试环境

# 概述

名称
地址 /connect/oauth2/sns_authorize?appid=APPID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=REDIRECT_URI&loginTmpCode=loginTmpCode
请求方式 GET
参数 见【参数】
返回值 见【返回值】

# 参数

参数 参数类型 必须 说明
appid String 扫码登录应用 appid
redirect_uri String 重定向地址,该地址使用域名需配置为 appid 对应的回调域名,回调域名是在获取 appId 及 appSecret 时填写。必填
state String 用于防止重放攻击,开发者可以根据此信息来判断 redirect_uri 只能执行一次来避免重放攻击, 选填
response_type String 固定为 code,必填
scope String 固定为 snsapi_login,必填
loginTmpCode String 通过 js 获取到的 loginTmpCode,必填

此链接处理成功后,会 302 跳转到你 goto 参数指定的 redirect_uri,并向 url 参数中追加临时授权码 code 及 state 两个参数。

# 通过临时授权码获取授权用户的个人信息

# host: https://yach-oapi.zhiyinlou.com  正式环境

# host: https://yach-oapi-test.zhiyinlou.com  测试环境

# 概述

名称
地址 /sns/getuserinfo_bycode
请求方式 POST
参数 见【参数】
返回值 见【返回值】

# 参数

参数 参数类型 必须 说明
tmp_auth_code String 用户授权的临时授权码 code,只能使用一次;在扫码后回调到设置的 redirect_uri 时会追加 code 参数

# URL 签名参数说明

参数 参数类型 必须 说明
accessKey String 扫码应用 appid
timestamp String 当前时间戳,单位是毫秒
signature String 通过扫码应用 appSecret 计算出来的签名值,签名计算方法

# Signature 参数

签名算法为 HmacSHA256,签名数据是当前时间戳 timestamp,密钥是 appId 对应的 appSecret 计算出来的签名值。

发送 HTTP 请求时需要把 signature 进行 urlEncode,如果您使用的是 HTTP 封装方法,请确保不要重复 urlEncode。

签名计算代码示例(PHP)

    // 根据timestamp, appSecret计算签名值
    $s = hash_hmac('sha256', 'timestamp', 'appSecret', true);
    $signature = base64_encode($s);
    var_dump($signature);
    $urlencode_signature = urlencode($signature);
    var_dump($urlencode_signature);

签名例子参考:

  • timestamp=1546084445901
  • appSecret=testappSecret
  • signature=HCbG3xNE3vzhO+u7qCUL1jS5hsu2n5r2cFhnTrtyDAE=
  • urlEncode 后的 signature=HCbG3xNE3vzhO%2Bu7qCUL1jS5hsu2n5r2cFhnTrtyDAE%3D

【注意】正常情况下 access_token 有效期为 7200 秒,有效期内重复获取返回相同结果。

返回值

{
  "code": 200,
  "msg": "",
  "obj": {
    "user_info": {
      "nick": "晋刚",
      "userid": "Yach076429"
    }
  }
}

返回值说明:

参数 说明
code 返回码
msg 对返回码的文本描述内容
obj 返回数据
userid 员工在当前企业内的唯一标识

# 获取快捷登录签名

# host: https://yach-oapi.zhiyinlou.com  正式环境

# host: https://yach-oapi-test.zhiyinlou.com  测试环境

# 概述

名称
地址 /connect/oauth2/quick_login_sign?access_token=ACCESS_TOKEN
请求方式 GET
参数 见【参数】
返回值 见【返回值】

# 参数

参数 参数类型 必须 说明
access_token String 接口调用凭证

返回值

{
  "code": 200,
  "msg": "",
  "obj": {
    "quick_sign": "string"
  }
}

返回值说明:

参数 说明
code 返回码
msg 对返回码的文本描述内容
obj 返回数据
quick_sign 快捷登录签名
上次更新: 2/3/2023, 11:21:58 AM
foo