• 企业微信接入芋道SpringBoot项目


    背景:使用芋道框架编写了一个数据看板功能需要嵌入到企业微信中,方便各级人员实时观看

    接入企业微信的话肯定不能像平常pc端一样先登录再根据权限看页面,不然的话不如直接手机浏览器打开登录账号来得更为方便,所以迎面而来面临两个问题

    1. 绕过原本遇到框架登录,企业微信点击后可以直接进入要看的数据看板功能

    2. 通过企业微信返还给我们的code拿去我们对应的人员信息等数据

    解决问题

    1. 绕过原本遇到框架登录,企业微信点击后可以直接进入要看的数据看板功能

    后端:

    在芋道框架中进入以上页面之后可以发现芋道后端接口的跳过权限校验的方法,也就是在配置文件中将接口路径写入进去即可,如下所示将对应接口路径写在该位置即可

    也可以使用注解@PermitAll:不管登入,不登入都能访问该方法 

    注:如果一个页面有多个接口那么所有接口均需要写上此注解,否则会提示登录状态过期 

    前端:

    src/router/indes.js页面中编写企业微信点击跳转后的路由

    src/permission.js页面中在whiteList将path路径名称加入,此时该页面不会检测是否存在token

    1. import router from './router'
    2. import store from './store'
    3. import { Message } from 'element-ui'
    4. import NProgress from 'nprogress'
    5. import 'nprogress/nprogress.css'
    6. import { getAccessToken } from '@/utils/auth'
    7. import { isRelogin } from '@/utils/request'
    8. NProgress.configure({ showSpinner: false })
    9. // 增加三方登陆 update by 芋艿
    10. const whiteList = ['/login', '/social-login', '/auth-redirect', '/bind', '/register', '/oauthLogin/gitee', '/loaginLevel', '/level']
    11. router.beforeEach((to, from, next) => {
    12. NProgress.start()
    13. if (getAccessToken()) {
    14. to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
    15. /* has token*/
    16. if (to.path === '/login') {
    17. next({ path: '/' })
    18. NProgress.done()
    19. } else {
    20. if (store.getters.roles.length === 0) {
    21. isRelogin.show = true
    22. // 获取字典数据 add by 芋艿
    23. store.dispatch('dict/loadDictDatas')
    24. // 判断当前用户是否已拉取完user_info信息
    25. store.dispatch('GetInfo').then(() => {
    26. isRelogin.show = false
    27. store.dispatch('GenerateRoutes').then(accessRoutes => {
    28. // 根据roles权限生成可访问的路由表
    29. router.addRoutes(accessRoutes) // 动态添加可访问路由表
    30. next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
    31. })
    32. }).catch(err => {
    33. store.dispatch('LogOut').then(() => {
    34. Message.error(err)
    35. next({ path: '/' })
    36. })
    37. })
    38. } else {
    39. next()
    40. }
    41. }
    42. } else {
    43. // 没有token
    44. if (whiteList.indexOf(to.path) !== -1) {
    45. // 在免登录白名单,直接进入
    46. next()
    47. } else {
    48. next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
    49. NProgress.done()
    50. }
    51. }
    52. })
    53. router.afterEach(() => {
    54. NProgress.done()
    55. })

    至此企业微信点击跳转已绕过登录页面,且不会检测token

    2. 通过企业微信返还给我们的code拿去我们对应的人员信息等数据

    引入依赖

    1. com.github.binarywang
    2. weixin-java-cp
    3. 4.4.0
    4. compile

    调用企业微信将code返还给企业微信换回用户信息,再根据用户信息拿到完整的用户信息,并生成token反馈给前端

    1. WxCpLettuceRedisConfigImpl config = new WxCpLettuceRedisConfigImpl(redisTemplate);
    2. // 注册的企业信息
    3. config.setCorpId(你的corpId);
    4. config.setCorpSecret(你的corpSecret);
    5. config.setAgentId(企业微信自研应用ID);
    6. WxCpService service = new WxCpServiceImpl();
    7. service.setWxCpConfigStorage(config);
    8. WxCpOauth2UserInfo userInfo = service.getOauth2Service().getUserInfo(code);
    9. String userId = userInfo.getUserId();
    10. // 使用账号密码,进行登录
    11. AdminUserDO user = userMapper.getUserInfoByUserId(userId);
    12. return createTokenAfterLoginUser(user.getId(), user.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME, user.getMobile());

    如需要WxCpLettuceRedisConfigImpl工具类可私信我获取

    调用原始方法生成token返回给前端,前端设置即可,至此接入企业微信完成(当然还需要有权限的人员给分配路跳转由,无需担心内网服务外部无法访问,企业微信对此有自己的特殊方式解决)

    接入后其他问题

    刷新页面code失效 无法获得数据

    企业微信提供的code是有时效的并且只可以消费一次,当我们刷新页面时code不会变,但是code已经消费过了去请求接口时会报错code异常,对于页面来说当然不算是报错还应该可以继续拿到信息,所以在前端直接把数据存到localStorage我们每次去localStorage拿取即可

    1. loginbycode() {
    2. let query = {
    3. code: this.getQueryVariable('code'),
    4. status: this.getQueryVariable('status')
    5. }
    6. loginbycode(query).then(response => {
    7. // 刷新页面时会再次请求此方法,此方法第二次请求返回的值都为null,我们仅需要保存第一次或者有值的即可
    8. if (response.data.userMobile != null){
    9. localStorage.setItem('userMobile', response.data.userMobile)
    10. }
    11. if (response.data.accessToken != null){
    12. localStorage.setItem('AccessTokenKey', response.data.accessToken)
    13. }
    14. if (response.data.refreshToken != null){
    15. localStorage.setItem('RefreshTokenKey', response.data.refreshToken)
    16. }
    17. this.params.mobile = localStorage.getItem('userMobile')
    18. getUserNumByUserRole(this.params).then(res => {
    19. this.userIn = res
    20. this.getListMsgByUserRole()
    21. this.getListMsg()
    22. });
    23. });
    24. },

  • 相关阅读:
    『docker笔记』Centos7离线安装docker[补充CentOS开机自动启动脚本]
    Dubbo高手之路3,Dubbo服务消费详解
    window 系统里 chrome 浏览器一些实用的调试技巧
    程序员应了解的那些事(109)C++的局部类
    Redis原理篇——内存回收
    华为机试真题实战应用【赛题代码篇】-打印任务排序(附Java、Python和C++代码)
    openai/chatgpt的api接口,各个模型的最大输入token一览表
    12.01 - 每日一题 - 408
    基于SSM的外卖点餐系统设计与实现
    Python中创建类的六重境界
  • 原文地址:https://blog.csdn.net/FanZaiYo/article/details/134073010