企业微信自动登录自定义系统

news2024/9/30 1:34:13

方法一:企业微信构造OAuth2链接跳转登录到自定义系统

企业微信自定义应用配置

  1. 构造网页授权链接

如果企业需要在打开的网页里面携带用户的身份信息,第一步需要构造如下的链接来获取code参数:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE&agentid=AGENTID#wechat_redirect

在这里插入图片描述
*注意,构造OAuth2链接中参数的redirect_uri是经过UrlEncode的*
在这里插入图片描述
2. 企业微信自定义应用配置

  • 设置可信域名,新应用首次配置需要下载可信用的txt文件上传到自定义系统服务器上,可信域名配置不支持ip地址
    在这里插入图片描述
    配置菜单调整链接
    在这里插入图片描述

  • 自定义系统配置
    前端根据跳转地址判断是不是企业微信跳转地址,根据code参数获取企业微信人员信息,userId对应企业微信的账号。
    后台使用 weixin-java-cp 插件

 /**
     * 获取企业微信访问用户身份
     * @param code
     * @param agentId
     * @param corpSecret
     * @return
     */
    public static Map<String, Object>  getOauthUser(String code, int agentId, String corpSecret) {
    	Map<String, Object> result = new HashMap<String, Object>();
    	WxCpService wxCpService = getWxCpService(Wxperson.getCorpId(),agentId,corpSecret);
    	try {
			WxCpOauth2UserInfo userInfo = wxCpService.getOauth2Service().getUserInfo(code);
			wxCpService.getJsapiTicket();
			if(null != userInfo) {
				result.put("code", "200");
				result.put("userId", userInfo.getUserId());
				result.put("deviceId", userInfo.getDeviceId());
			}
    	} catch (Exception e) {
			e.printStackTrace();
			result.put("code", "500");
			result.put("message", e.getMessage());
		}
    	return result;
    }

方法二:使用js-skd,可设置跳转到默认浏览器打开

  1. wx.config
    通过wx.config注入应用的权限,在index.html文件中通过 script 引入
    <script src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
    <script src="https://wwcdn.weixin.qq.com/node/open/js/wecom-jssdk-1.3.1.js"></script>
  1. 前端增加企业微信登录页面wechatCPLogin.vue,后台构造OAuth2链接
<template>
    <div></div>
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue'
import { wechatConfig, getWechatOauth2Url } from '@/api/login'
import { HSoft } from '@/utils/hsoft'
import { useRouter } from 'vue-router'
import type { RouteLocationNormalizedLoaded } from 'vue-router'
import { ElMessage } from 'element-plus'

const { currentRoute, push } = useRouter()

const redirect = ref<string>('')

const otherQuery = ref({})

let wx =  window.wx

const userAgent = window.navigator.userAgent;

watch(
  () => currentRoute.value,
  (route: RouteLocationNormalizedLoaded) => {
    redirect.value = route?.query?.redirect as string
    otherQuery.value = getOtherQuery(route?.query)
  },
  {
    immediate: true
  }
)


function getOtherQuery(query: any) {
  return Object.keys(query).reduce((acc: any, cur: any) => {
    if (cur !== 'redirect') {
      acc[cur] = query[cur]
    }
    return acc
  }, {})
}

function getWeConfig() {
    console.log(window.navigator.userAgent,"HHHHH");
    //openDefaultBrowser()
    if(userAgent.includes('wxwork')) {
        if(userAgent.includes('Windows') || userAgent.includes('Mac')){
            let params = {
            // 当前网页的URL,不包含#及其后面部分,签名算法的时候会用到
            url: window.location.href.split("#")[0],
            agentId: HSoft.AGENTID,
            corpSecret: HSoft.CORPSECRET
            }
            
            wechatConfig(params).then(res => {
            console.log(res);
            const data = res.data;
            wx.config({
                beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
                debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: data.appId, // 必填,企业微信的corpID,必须是本企业的corpID,不允许跨企业使用
                timestamp: data.timestamp, // 必填,生成签名的时间戳
                nonceStr: data.nonceStr, // 必填,生成签名的随机串
                signature: data.signature,// 必填,签名,见 附录-JS-SDK使用权限签名算法
                jsApiList: ['openDefaultBrowser'] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
            });
            wx.ready(function () {
            //执行你的业务逻辑代码
                    //......
                    //如果要使用到agent_config相关接口 初始化agentConfig配置
                openDefaultBrowser()    
                //getWechatAgentConfig()
            });
            wx.error(function (res) {
                console.log(res);
                // config信息验证失败会执行error函数,如签名过期导致验证失败
                // ,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,
                // 对于SPA可以在这里更新签名。
            });
            }).catch(err => {
            console.log(err)
            })
        }else{
            let params = {
                url: otherQuery.value['url'],
                agentId: HSoft.AGENTID,
                corpSecret: HSoft.CORPSECRET,
                state: 'wechatCP',
            }
            getWechatOauth2Url(params).then(res => {
                console.log(res);
                location.href = res.data.url;
            })
        }
    }else{
        push(`/login?unauto=true`)
    }
}

function openDefaultBrowser(){
    let params = {
        url: otherQuery.value['url'],
        agentId: HSoft.AGENTID,
        corpSecret: HSoft.CORPSECRET,
        state: 'wechatCP',
    }
    getWechatOauth2Url(params).then(res => {
        console.log(res);
        
        //if((userAgent.includes('Windows') || userAgent.includes('Mac'))){
            wx.invoke('openDefaultBrowser', {
                // 在默认浏览器打开redirect_uri,并附加code参数;也可以直接指定要打开的url,此时不会附带上code参数。
            // 'url': "https://open.weixin.qq.com/connect/oauth2/authorize?appid=******&redirect_uri=http%3A%2F%2Fabc.com%3A6868%2Fwechat%2Fpc&response_type=code&scope=snsapi_userinfo&agentid=**&state=STATE#wechat_redirect"
                'url': res.data.url
            }, function(res){
                console.log('res------------->', res)
                if(res.err_msg != "openDefaultBrowser:ok"){
                    //错误处理
                    ElMessage.error("企业微信授权登录地址获取异常,请使用账号密码登录")
                    push(`/login?unauto=true`)
                }else{
                    wx.closeWindow();
                    window.close();
                }
            })
            
        // }else{
        //     location.href = res.data.url;
        // }
    }).catch(err => {
        console.log(err)
    })
    
}
onMounted(() => {
    getWeConfig();
})

</script>

后台方法 wechatConfig

public static Map<String, Object> wechatConfig(String url, Integer agentId, String corpSecret) {
    	Map<String, Object> result = new HashMap<String, Object>();
    	WxCpService wxCpService = getWxCpService(Wxperson.getCorpId(),agentId,corpSecret);
	    try {
			WxJsapiSignature createJsapiSignature = wxCpService.createJsapiSignature(url);
			if(null != createJsapiSignature) {
				result.put("code", "200");
				result.put("appId",createJsapiSignature.getAppId());
				result.put("timestamp",createJsapiSignature.getTimestamp());
				result.put("nonceStr",createJsapiSignature.getNonceStr());
				result.put("signature",createJsapiSignature.getSignature());
			}
			
	    } catch (Exception e) {
			e.printStackTrace();
			result.put("code", "500");
			result.put("message", e.getMessage());
		}
		return result;
	}

getWechatOauth2Url

public static Map<String, Object> getWechatOauth2Url(String url, Integer agentId, String corpSecret, String state, String scope) {
    	Map<String, Object> result = new HashMap<String, Object>();
    	WxCpService wxCpService = getWxCpService(Wxperson.getCorpId(),agentId,corpSecret);
	    try {
			String buildAuthorizationUrl = wxCpService.getOauth2Service().buildAuthorizationUrl(url, state, scope);
			if(HSoft.isNotEmpty(buildAuthorizationUrl)) {
				result.put("code", "200");
				result.put("url",buildAuthorizationUrl);
			}
			
	    } catch (Exception e) {
			e.printStackTrace();
			result.put("code", "500");
			result.put("message", e.getMessage());
		}
		return result;
	}
  1. 剩余步骤参考方法一

企业微信扫码登录自定义系统

企业微信web登录

  1. 使用企业微信 JS-SDK:wecom/jssdk >=1.3.1
    通过 script 标签引入
<script src="https://wwcdn.weixin.qq.com/node/open/js/wecom-jssdk-1.3.1.js"></script>
  1. 创建企业微信登录面板
    API接口 ww.createWWLoginPanel
<!--企业微信扫码登录-->
<template>
    <div id="wechatScanLogin" >
    </div>
</template>

<script setup lang="ts">
import { onMounted } from 'vue'
import { HSoft } from '@/utils/hsoft'

// 初始化
const wwLogin = () => {
    window.ww.createWWLoginPanel({
      el: '#wechatScanLogin',
      params: {
        login_type: 'CorpApp',
        appid: HSoft.APPID,
        agentid: HSoft.AGENTID,
        redirect_uri: 'http://xxx.xxx.com:8088/login',
        state: 'loginState',
        redirect_type: 'callback',
      },
      onCheckWeComLogin({ isWeComLogin }) {  // 企业微信桌面端是否已登录
        console.log(isWeComLogin)
      },
      onLoginSuccess({ code }) {	// 企业微信登录成功回调 Auth Code
        console.log({ code })
        //调用获取企业微信自动登录接口
      },
      onLoginFail(err) {
        console.log(err)
      },
    })
} 

onMounted( () => {
    wwLogin()
})

</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1322906.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重新配置torch1.8 cuda11.1 torchtext0.9.0虚拟Pytorch开发环境

这里写目录标题 起因发现选择安装cuda 11.1核对下自己的显卡是否支持下载该版本的CUDACUDA下载地址CUDA安装过程在anaconda中创建一个虚拟环境1.以下是环境的配置过程2.查看虚拟环境列表3.激活虚拟环境4.输入这句代码&#xff0c;没想到就可以直接安装torch和torchtext了[网站在…

计算机基础,以及实施运维工程师介绍

目录 一.实施&#xff0c;运维工程师介绍 1.什么是实施工程师&#xff1f; 实施工程师职责 2.什么是运维工程师&#xff1f; 运维工程师职责 3.实施运维需要的技术 数据库 操作系统 网络 服务器 软件 硬件 网络 二.计算机介绍 CPU 存储器 io 总线 主板 三.操…

【lesson18】MySQL内置函数(1)日期函数和字符串函数

文章目录 日期函数函数使用具体使用案例建表插入数据建表插入数据 字符串函数函数使用具体使用案例建表插入数据测试 日期函数 函数使用 获得年月日&#xff1a; 获得时分秒&#xff1a; 获得时间戳&#xff1a; 获得现在的时间&#xff1a; 在日期的基础上加日期&#xf…

JavaWeb 学生信息管理系统

介绍 ServletMysqlJdbcjQuery 实现学生信息管理系统 学生 班级 教师 系统设置 登陆 软件架构 软件架构说明 基于ServletMysqlJdbcjQuery 实现学生信息的增删改查功能 文件目录声明 src/dao 数据库的增删改查功能src/filter 网页的过滤拦截功能src/model 登陆的实体对象信息…

深度学习 Day19——P8YOLOv5-C3模块实现

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 文章目录 前言1 我的环境2 代码实现与执行结果2.1 前期准备2.1.1 引入库2.1.2 设置GPU&#xff08;如果设备上支持GPU就使用GPU,否则使用C…

[BJDCTF2020]Mark loves cat1

提示 -信息收集.git泄露php代码审计 拿到题先做信息收集 这里用dirsearch扫了下目录 ###如果没有dirsearch我在之前的这篇博客有写dirsearch的安装环境以及地址还有怎么扫buuctf里的题 [GXYCTF2019]禁止套娃1-CSDN博客 从扫描结果来看这里存在git泄露 这里使用githack拉下来git…

Java并发(二十)----synchronized原理进阶

1、小故事 故事角色 老王 - JVM 小南 - 线程 小女 - 线程 房间 - 对象 房间门上 - 防盗锁 - Monitor-重量级锁 房间门上 - 小南书包 - 轻量级锁 房间门上 - 刻上小南大名 - 偏向锁 -对象专属于某个线程使用 批量重刻名 - 一个类的偏向锁撤销到达 20 阈值 -批量重偏向 …

从企业的角度看待WMS仓储管理系统的集成

随着全球化和数字化的发展&#xff0c;企业面临着越来越复杂的商业环境。为了满足高效运营的需求&#xff0c;许多企业开始寻求更先进、更集成的解决方案来优化他们的仓储流程。WMS仓储管理系统作为一种重要的解决方案&#xff0c;在企业中发挥着关键的作用。本文将从企业的角度…

Android studio Android SDK下载安装

我们访问地址 https://developer.android.google.cn/studio?hlzh-cn 拉下来直接点击下载 然后来下来 勾选 然后点击下载 下载好之后 我们双击打开 点击下一步 确认上面的勾选 然后下一步 这里 我们选择一下安装目录 然后点击下一步 安装 安装完之后点击进行下一步 Fin…

echarts 饼图3样式

父组件&#xff1a; <pieChartNormal :opt"contractStatics" style"width: 100%;height: 100%;" />import pieChartNormal from "./components/pieChartNormal";data() {return {contractStatics: {seriesData: [{name: 技术服务类,value:…

Gemini Pro API 详细申请步骤

Gemini Pro API 详细申请步骤 什么是 Gemini ? 上周&#xff0c;谷歌发布了 Gemini&#xff08;双子座&#xff09;&#xff0c;它是谷歌最新、最强大的人工智能模型&#xff0c;旨在迎头痛击 OpenAI 的 GPT。Gemini 在构建时考虑到了多模态性&#xff0c;这意味着它能够理解…

SG3524控制的恒流源电路图

SG3524简介 SG3524是开关电源脉宽调制型控制器。应用于开关稳压器&#xff0c;变压器耦合的直流变换器&#xff0c;电压倍增器&#xff0c;极性转换器等。采用固定频率&#xff0c;脉冲宽度调制&#xff08;脉宽调制&#xff09;技术。输出允许单端或推挽输出。芯片电路包括电…

卸载MySQL——Windows

1. 停止MySQL服务 winR 打开运行&#xff0c;输入 services.msc 点击 “确定” 调出系统服务。 我这里只有一个&#xff0c;只要是以MySQL开头的全部停止 2. 卸载MySQL相关组件 打开控制面板 —> 卸载程序 —> 卸载MySQL相关所有组件 3. 删除MySQL安装目录 一般是C:\P…

Oracle的学习心得和知识总结(三十)| OLTP 应用程序的合成工作负载生成器Lauca论文翻译及学习

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《Oracle Database SQL Language Reference》 2、参考书籍&#xff1a;《PostgreSQL中文手册》 3、EDB Postgres Advanced Server User Gui…

Tomcat-指定启动jdk、修改使用的jdk版本

修改tomcat配置文件setclasspath.sh 配置文件首行增加以下代码&#xff0c;指定启动的jdk&#xff1a; export JAVA_HOME/opt/softwares/jdk1.8.0_211/ export JRE_HOME/opt/softwares/jdk1.8.0_211/jre

详解—C++ [异常]

目录 一、C语言传统的处理错误的方式 二、C异常概念 三、异常的使用 3.1 异常的抛出和捕获 3.2 异常的重新抛出 3.3异常安全 3.4 异常规范 四、自定义异常体系 五、C标准库的异常体系 六、异常的优缺点 6.1、C异常的优点&#xff1a; 6.2、C异常的缺点&#xff1a;…

Transformer的学习

文章目录 Transformer1.了解Seq2Seq任务2.Transformer 整体架构3.Encoder的运作方式4.Decoder的运作方式5.AT 与 NAT6.Encoder 和 Decoder 之间的互动7.Training Transformer 1.了解Seq2Seq任务 NLP 的问题&#xff0c;都可以看做是 QA&#xff08;Question Answering&#x…

C语言程序设计·头歌实训合集

C语言程序设计实训 C语言程序设计编辑与调试环境 任何高级语言源程序都要“翻译”成机器语言&#xff0c;才能在机器上运行。“翻译”的方式有两种&#xff1a;一种是解释方式&#xff0c;即对源程序解释一句执行一句&#xff1b;另一种是编译方式&#xff0c;即通过编译系统…

Python----进程的注意点

1. 进程的注意点介绍 进程之间不共享全局变量主进程会等待所有的子进程执行结束再结束 2. 进程之间不共享全局变量 import multiprocessing import time# 定义全局变量 g_list list()# 添加数据的任务 def add_data():for i in range(5):g_list.append(i)print("add:&…

你在为其他知识付费平台做流量吗?

随着知识付费市场的蓬勃发展&#xff0c;越来越多的知识提供者选择将自己的课程放到各大知识付费平台上进行销售。然而&#xff0c;你是否意识到&#xff0c;你正在为这些平台做流量、做数据、做流水、做品牌&#xff0c;而卖出去的课程平台还要抽取你的佣金&#xff1f; 如果…