企业微信授权登录(uniapp项目)

发布于:2025-06-08 ⋅ 阅读:(16) ⋅ 点赞:(0)

开发之前必须把这张图了解透了,不然会容易做着做着懵,没有思路。

官方地址:https://developer.work.weixin.qq.com/document/path/98151

一、前端页面

login登录页,

<template>
	<view class="login-container">
		
		<button class="form-button wecom" @click="handleWecomLogin">
			企业微信登录
		</button>
	</view>
</template>
	function handleWecomLogin() {
		const CORPID = 'ww7981ebca139e75f9'
		const REDIRECT_URI='https://datalab.ffep.online:20093/web/pages/index/callback'	// 返回授权登录码
		const AGENTID='1000086'
	  // 生成授权URL
	  // const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${CORPID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=snsapi_base&agentid=${AGENTID}&state=login`;
	  const authUrl = `https://login.work.weixin.qq.com/wwlogin/sso/login?login_type=CorpApp&appid=${CORPID}&redirect_uri=${REDIRECT_URI}&state=STATE&agentid=${AGENTID}`
	  // 跳转到企业微信授权页面
	    window.location.href = authUrl;
	}
		
</script>

<style lang="scss" scoped>
	/*省略*/
</style>

callback回调页

<template>
  <view></view>
</template>

<script setup lang="ts">
import { onLoad } from '@dcloudio/uni-app';
import request from '../../utils/hrAPI';

onLoad(async (options) => {
  if (options.code) {
    try {
      // 使用授权码换取用户信息并登录
      // const res = await loginWithWecomCode(options.code);
	  const res = await request({
	    url: '/ffep/Wecom/loginWithWecomCode',
	    method: 'POST',
	    data: {code:options.code},
	    requiresAuth:false
	  });
      
      if (res.code === 1) {
        uni.setStorageSync('staffinfo', res.data.staffinfo);
        uni.showToast({ title: '登录成功', icon: 'success' });
        uni.reLaunch({ url: '/pages/index/index' });
      } else {
        uni.showToast({ title: res.msg, icon: 'none' });
        // uni.navigateBack();
      }
    } catch (error) {
      console.error('企业微信登录失败:', error);
      uni.showToast({ title: '网络错误,请重试', icon: 'none' });
      // uni.navigateBack();
    }
  } else {
    // uni.navigateBack();
  }
});
</script>

二、后端准备

准备一个控制器

<?php
namespace app\api\controller\ffep;

use app\common\controller\Api;
use think\Db;
use think\Request;
use addons\wecom\library\Wecom as wecomService;
use think\Exception;
use think\Cache;
use app\admin\model\wecom\Staff;

class Wecom extends Api
{
    protected $noNeedLogin = ['*'];
    protected $noNeedRight = ['*'];

    // IT尊享服务
    protected $app_id = "1000086";
    protected $app_secret = "T3jVYGDudwKnz3k1u50EXT3LhcOnUm5Z3cN-mXRutlo";

    protected $corpid;
    protected $corpsecret;

    public function __construct()
    {
        parent::__construct();
        // 企微的公司id和密钥
        $this->corpid = $config['corpid'];  
        $this->corpsecret = $config['secret']; 
    }
    
    // callback回调页面会访问这个方法,请求用户id
    public function loginWithWecomCode(){
        // 注意这里要拿应用的accesstoken,查看token的权限地址https://developer.work.weixin.qq.com/devtool/query
        $accessToken = $this->getAppAccessToken($this->app_id,$this->app_secret);
        $code = $this->request->param('code',false);
        if($code){
            $url = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=$accessToken&code=$code";
            //发送一个POST请求并获取返回结果
            $result = \fast\Http::get($url);
            $result = json_decode($result);
            // dump($result);exit;
            if(isset($result->userid)){
                // 拿到用户userid的业务逻辑
                $userid = $result->userid;
                $staffinfo = Staff::where('userid',$userid)->find();
                if(!$staffinfo){
                    $this->error('企业微信信息获取失败。请联系管理员');
                }else{
                    // 获取成功的流程
                    $this->success('授权成功',['staffinfo'=>$staffinfo]);
                }
            }else{
                $this->error('企业微信授权登录失败。请重试');
            }
        }
    }
    
    /**
     * 获取JS-SDK配置
     */
    public function jssdkConfig()
    {
        // dump(Request::instance());exit;
        $url = $this->request->post('url');
        if (!$url) {
            $this->error('缺少URL参数');
        }
        
        try {
            $config = $this->getJssdkConfig($url);
            $this->success('获取成功', $config);
        } catch (Exception $e) {
            $this->error('获取失败: ' . $e->getMessage());
        }
    }
    
    /**
     * 生成JS-SDK配置
     */
    private function getJssdkConfig($url)
    {
        $corpid = $this->corpid;
        $corpsecret = $this->corpsecret;
        
        // 获取access_token
        $accessToken = $this->getAccessToken();
        
        // 获取jsapi_ticket
        $jsapiTicket = $this->getJsapiTicket($accessToken);
        
        // 生成签名
        $nonceStr = $this->createNonceStr();
        $timestamp = time();
        $signature = $this->generateSignature($jsapiTicket, $nonceStr, $timestamp, $url);
        
        return [
            'appId' => $corpid,
            'nonceStr' => $nonceStr,
            'timestamp' => $timestamp,
            'signature' => $signature,
            'jsApiList' => ['checkJsApi', 'scanQRCode'] // 需要使用的接口列表
        ];
    }
    
    // 获取应用的accesstoken
    public function getAppAccessToken($agentid,$appsecret)
    {
        $token = Cache::get($agentid.'_wecom_access_token');
        if (!$token) {
            $config = get_addon_config('wecom');
            $corpid = $this->corpid;
            $corpsecret = $appsecret;
            $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$corpid}&corpsecret={$corpsecret}";
            $result = $this->httpGet($url);
            $result = json_decode($result, true);
             
            if (isset($result['access_token'])) {
                $accessToken = $result['access_token'];
                Cache::set($agentid.'_wecom_access_token', $accessToken, 7100); // 提前100秒过期
            } else {
                throw new Exception('获取access_token失败: ' . json_encode($result));
            }
        }
        return $token;
    }
    
    /**
     * 获取access_token
     */
    private function getAccessToken()
    {
        // 从缓存获取或重新请求
        $accessToken = Cache::get('wecom_access_token');
        if (!$accessToken) {
            $corpid = $this->corpid;
            $corpsecret = $this->corpsecret;
            
            $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$corpid}&corpsecret={$corpsecret}";
            $result = $this->httpGet($url);
            $result = json_decode($result, true);
            
            if (isset($result['access_token'])) {
                $accessToken = $result['access_token'];
                Cache::set('wecom_access_token', $accessToken, 7100); // 提前100秒过期
            } else {
                throw new Exception('获取access_token失败: ' . json_encode($result));
            }
        }
        
        return $accessToken;
    }
    
    /**
     * 获取jsapi_ticket
     */
    private function getJsapiTicket($accessToken)
    {
        // 从缓存获取或重新请求
        $jsapiTicket = Cache::get('wecom_jsapi_ticket');
        if (!$jsapiTicket) {
            $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token={$accessToken}";
            $result = $this->httpGet($url);
            $result = json_decode($result, true);
            
            if (isset($result['ticket'])) {
                $jsapiTicket = $result['ticket'];
                Cache::set('wecom_jsapi_ticket', $jsapiTicket, 7100); // 提前100秒过期
            } else {
                throw new Exception('获取jsapi_ticket失败: ' . json_encode($result));
            }
        }
        
        return $jsapiTicket;
    }
    
    /**
     * 生成签名
     */
    private function generateSignature($jsapiTicket, $nonceStr, $timestamp, $url)
    {
        $string = "jsapi_ticket={$jsapiTicket}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";
        return sha1($string);
    }
    
    /**
     * 创建随机字符串
     */
    private function createNonceStr($length = 16)
    {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }
    
    /**
     * HTTP GET请求
     */
    private function httpGet($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }
}

三、实践过程中遇到的问题&解决办法

解决:

 

not allow to access from your ip