• 企业微信自建应用手动授权,获取用户详细信息


    开始开发

    最后更新:2022/10/11

    企业微信提供了OAuth的授权登录方式,可以让从企业微信终端打开的网页获取成员的身份信息,从而免去登录的环节。
    企业应用中的URL链接(包括自定义菜单或者消息中的链接),均可通过OAuth2.0验证接口来获取成员的UserId身份信息。

    OAuth2简介

    OAuth2的设计背景,在于允许用户在不告知第三方自己的帐号密码情况下,通过授权方式,让第三方服务可以获取自己的资源信息。
    详细的协议介绍,开发者可以参考RFC 6749

    下面简单说明OAuth2中最经典的Authorization Code模式,流程如下:

    流程图中,包含四个角色。

    • ResourceOwner为资源所有者,即为用户
    • User-Agent为浏览器
    • AuthorizationServer为认证服务器,可以理解为用户资源托管方,比如企业微信服务端
    • Client为第三方服务

    调用流程为:
    A) 用户访问第三方服务,第三方服务通过构造OAuth2链接(参数包括当前第三方服务的身份ID,以及重定向URI),将用户引导到认证服务器的授权页
    B) 用户选择是否同意授权
    C) 若用户同意授权,则认证服务器将用户重定向到第一步指定的重定向URI,同时附上一个授权码。
    D) 第三方服务收到授权码,带上授权码来源的重定向URI,向认证服务器申请凭证。
    E) 认证服务器检查授权码和重定向URI的有效性,通过后颁发AccessToken(调用凭证)

    D)与E)的调用为后台调用,不通过浏览器进行

    获取访问用户身份

    最后更新:2022/09/23

    该接口用于根据code获取成员信息,适用于自建应用与代开发应用

    请求方式:GET(HTTPS
    请求地址:https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
    参数说明:

    参数必须说明
    access_token调用接口凭证
    code通过成员授权获取到的code,最大为512字节。每次成员授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

    权限说明:
    跳转的域名须完全匹配access_token对应应用的可信域名,否则会返回50001错误。
    返回结果:
    a) 当用户为企业成员时(无论是否在应用可见范围之内)返回示例如下:

    1. {
    2. "errcode": 0,
    3. "errmsg": "ok",
    4. "userid":"USERID",
    5. "user_ticket": "USER_TICKET"
    6. }

    获取访问用户敏感信息

    最后更新:2022/09/19

    自建应用与代开发应用可通过该接口获取成员授权的敏感字段

    请求方式:POST(HTTPS
    请求地址:https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail?access_token=ACCESS_TOKEN

    请求包体:

    1. {
    2. "user_ticket": "USER_TICKET"
    3. }

    参数说明:

    参数必须说明
    access_token调用接口凭证
    user_ticket成员票据

    权限说明:
    成员必须在应用的可见范围内。

    返回结果:

    1. {
    2. "errcode": 0,
    3. "errmsg": "ok",
    4. "userid":"lisi",
    5. "gender":"1",
    6. "avatar":"http://shp.qpic.cn/bizmp/xxxxxxxxxxx/0",
    7. "qr_code":"https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=vcfc13b01dfs78e981c",
    8. "mobile": "13800000000",
    9. "email": "zhangsan@gzdev.com",
    10. "biz_mail":"zhangsan@qyycs2.wecom.work",
    11. "address": "广州市海珠区新港中路"
    12. }

    参数说明:

    参数说明
    errcode返回码
    errmsg对返回码的文本描述内容
    userid成员UserID
    gender性别。0表示未定义,1表示男性,2表示女性。仅在用户同意snsapi_privateinfo授权时返回真实值,否则返回0.
    avatar头像url。仅在用户同意snsapi_privateinfo授权时返回
    qr_code员工个人二维码(扫描可添加为外部联系人),仅在用户同意snsapi_privateinfo授权时返回
    mobile手机,仅在用户同意snsapi_privateinfo授权时返回,第三方应用不可获取
    email邮箱,仅在用户同意snsapi_privateinfo授权时返回,第三方应用不可获取
    biz_mail企业邮箱,仅在用户同意snsapi_privateinfo授权时返回,第三方应用不可获取
    address仅在用户同意snsapi_privateinfo授权时返回,第三方应用不可获取

    注:对于自建应用与代开发应用,敏感字段需要管理员在应用详情里选择,且成员oauth2授权时确认后才返回。敏感字段包括:性别、头像、员工个人二维码、手机、邮箱、企业邮箱、地址。

    上一篇

     


     

    https://open.weixin.qq.com/connect/oauth2/authorize?appid=wwd70ee88af370290f&redirect_uri=http://yuying-api.xutongbao.top/index1.html&response_type=code&scope=snsapi_privateinfo&agentid=1000004&state=STATE#wechat_redirect

    https://open.weixin.qq.com/connect/oauth2/authorize?appid=wwd70ee88af370290f&redirect_uri=http://yuying-api.xutongbao.top/index1.html&response_type=code&scope=snsapi_privateinfo&agentid=1000004&state=STATE#wechat_redirect

     

    https://developer.work.weixin.qq.com/document/path/91022

    接口:

    1. const toolsQiWeUserInfo = async (req, res) => {
    2. const { code } = req.body
    3. axios({
    4. url: 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wwd70e*****290f&corpsecret=JrPSfOHlNzPiF******CV4VPwUuuHwAxyUdUDu8',
    5. }).then((resData) => {
    6. let access_token = resData.data.access_token
    7. axios({
    8. url: `https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo`,
    9. params: {
    10. access_token,
    11. code,
    12. debug: 1,
    13. },
    14. }).then((resData) => {
    15. console.log(res)
    16. let userInfo = resData.data
    17. axios({
    18. url: `https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail?access_token=${access_token}&debug=1`,
    19. data: {
    20. user_ticket: userInfo.user_ticket
    21. },
    22. method: 'post'
    23. }).then((resData) => {
    24. console.log(res)
    25. res.send({
    26. code: 200,
    27. data: {
    28. userInfo,
    29. userDetail: resData.data
    30. },
    31. message: '成功',
    32. })
    33. })
    34. })
    35. })
    36. }

    前端:

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8" />
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    7. <title>Documenttitle>
    8. <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js">script>
    9. <script
    10. src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"
    11. referrerpolicy="origin"
    12. ref
    13. >script>
    14. <script src="lib/axios.min.js">script>
    15. <style>
    16. .m-info {
    17. white-space: pre;
    18. }
    19. .m-img {
    20. width: 200px;
    21. height: 200px;
    22. }
    23. style>
    24. head>
    25. <body>
    26. <div>
    27. <div>信息div>
    28. <div><span id="m-info" class="m-info">span>div>
    29. <div>群ID:<span id="m-chat-id">span>div>
    30. div>
    31. <script src="lib/vconsole.min.js">script>
    32. <script>
    33. // VConsole will be exported to `window.VConsole` by default.
    34. var vConsole = new window.VConsole()
    35. script>
    36. <script>
    37. console.log(location.href)
    38. axios({
    39. url: `http://yuying-api.xutongbao.top/api/light/tools/qiWeToken`,
    40. method: 'post',
    41. data: {
    42. url: location.href,
    43. },
    44. }).then((res) => {
    45. console.log(res)
    46. const agentFun = () => {
    47. const { timestamp, noncestr, signature } = res.data.data.agentData
    48. wx.agentConfig({
    49. corpid: 'wwd70e*****290f', // 必填,企业微信的corpid,必须与当前登录的企业一致
    50. agentid: '1000004', // 必填,企业微信的应用id (e.g. 1000247)
    51. timestamp, // 必填,生成签名的时间戳
    52. nonceStr: noncestr, // 必填,生成签名的随机串
    53. signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
    54. jsApiList: ['getCurExternalChat'], //必填,传入需要使用的接口名称
    55. success: function (res) {
    56. console.log(666, res)
    57. wx.invoke('getCurExternalChat', {}, function (res) {
    58. console.log(777, res)
    59. if (res.err_msg == 'getCurExternalChat:ok') {
    60. let chatId = res.chatId //返回当前外部群的群聊ID
    61. document.getElementById('m-chat-id').innerHTML = chatId
    62. } else {
    63. //错误处理
    64. }
    65. })
    66. // 回调
    67. },
    68. fail: function (res) {
    69. console.log(res)
    70. if (res.errMsg.indexOf('function not exist') > -1) {
    71. alert('版本过低请升级')
    72. }
    73. },
    74. })
    75. console.log(timestamp, noncestr, signature)
    76. }
    77. agentFun()
    78. getUserInfo({
    79. access_token: res.data.data.corpData.tokenData.access_token,
    80. })
    81. })
    82. const parseQueryString = (url) => {
    83. let params = {}
    84. let arr = url.split('?')
    85. if (arr.length <= 1) {
    86. return params
    87. }
    88. arr = arr[1].split('&')
    89. for (let i = 0, l = arr.length; i < l; i++) {
    90. let a = arr[i].split('=')
    91. params[a[0]] = a[1]
    92. }
    93. return params
    94. }
    95. const getUserInfo = ({ access_token }) => {
    96. let qs = parseQueryString(location.href)
    97. let code = qs.code
    98. axios({
    99. url: `http://yuying-api.xutongbao.top/api/light/tools/qiWeUserInfo`,
    100. method: 'post',
    101. data: {
    102. code,
    103. },
    104. }).then((res) => {
    105. console.log(res)
    106. if (res.data.code === 200) {
    107. const { mobile, userid, avatar, qr_code } = res.data.data.userDetail
    108. console.log(avatar)
    109. console.log(qr_code)
    110. document.getElementById('m-info').innerHTML = `
    111. 手机号:${mobile}
    112. UserId: ${userid}
    113. ${avatar}" class="m-img" />
    114. ${qr_code}" class="m-img" />
      `
    115. }
    116. })
    117. }
    118. script>
    119. body>
    120. html>

     

     

  • 相关阅读:
    echarts 多个数据xAxis和series读取(Object.values使用)
    iOS开发之编译OpenSSL静态库
    Springboot的房屋租赁租房系统049
    关于电路的输入阻抗与输出阻抗的理解
    docker导致root空间满进入不了系统解决方案
    设计模式:外观模式
    TypeError: Argument ‘angle‘ can not be treated as a double
    包装类与数据类型
    stm32---定时器输入捕获
    ATK-ESP8266使用说明(STM32-F4)
  • 原文地址:https://blog.csdn.net/xutongbao/article/details/128025797