企微登录功能对接
基本参数说明
官方文档参考:developer.work.weixin.qq.com/docum...
参数 | 定义 | 说明 |
---|---|---|
corpid | 企业唯一的corpid | 获取此信息:管理后台 “我的企业-企业信息 - 企业ID”(需要有管理员权限) |
userid | 成员唯一的userid | 所谓“账号” |
partyid | 部门id | 管理后台 - 通讯录 - 组织架构 - 部门 |
tagid | 标签id | 管理后台 - 通讯录 - 标签 |
external_userid | 企业外部联系人的id | 可能是微信用户,也可能是企业微信用户 |
agentid | 每个应用唯一的agentid | 管理后台 - 应用管理 - 应用,点进应用,即可看到agentid |
secret | secret每个应用的访问密钥都是独立的 | secret是企业应用保障数据安全的“钥匙”,管理后台-应用管理-应用,点进应用,即可看到 |
自建应用配置
在创建应用之后,为避免踩坑。优先配置:可信域名+可信IP+可见范围,可让你的开发调试更加流畅。。。
- “可信域名”:在管理后台->“应用管理”->“应用”,点进某个应用,开发者接口模块即可配置
- “可信IP”:同上。从2022年6月20号20点之后必须配置,所以开发前都先配上
- “可见范围”:非必要情况也配置为全部,需权限管控的列外
获取access_token
access_token是所有接口在通信时都需要携带此信息用于验证接口的访问权限。
核心代码:
<?php
namespace App\Service;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class OpenWeChatService
{
/**
* 企微Id
* @var string
*/
public $corpid;
/**
* 应用唯一id
* @var string
*/
public $agentid;
/**
* 应用密钥
* @var string
*/
public $secret;
/**
* access_token 本地缓存key
*/
const OPEN_ACCESS_TOKEN_CACHE_KEY = 'OpenWeChat-AccessToken-';
/**
* access_token 本地缓存时间,不可大于7200
*/
const OPEN_ACCESS_TOKEN_CACHE_TIME = 3600;
public function __construct()
{
$this->corpid = config('openwechat.corpid');
$this->agentid = config('openwechat.agentid');
$this->secret = config('openwechat.secret');
}
/**
* 获取企微openApi的 access_token,通过【access_token + 消息请求】获取【请求结果】
* 无需每次获取。通常设置一个过期周期,一般2小时【官方默认】,失效后才获取
* 【GET】https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
* @return string
* @throws \Exception
*/
public function _getAccessToken(): string
{
$url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=' . $this->corpid . '&corpsecret=' . $this->secret;
try {
$response = Http::get($url)->json();
} catch (\Exception $e) {
throw new \Exception('获取access_token,请求失败:' . $url);
}
if (isset($response['errcode']) && $response['errcode'] <> 0) {
throw new \Exception('获取access_token失败,errcode:' . $response['errcode'] ?? '');
}
$accessToken = $response['access_token'];
return $accessToken;
}
/**
* 本地缓存:获取企微openApi的 access_token
* @param $cache
* @return mixed|string
* @throws \Exception
*/
public function getAccessToken($cache = true): string
{
if ($cache) {
$openAccessTokenCacheKey = self::OPEN_ACCESS_TOKEN_CACHE_KEY . $this->corpid;
$openAccessTokenCache = Cache::get($openAccessTokenCacheKey);
if ($openAccessTokenCache) {
return $openAccessTokenCache;
}
$accessToken = $this->_getAccessToken();
Cache::put($openAccessTokenCacheKey, $accessToken, self::OPEN_ACCESS_TOKEN_CACHE_TIME);
} else {
$accessToken = $this->_getAccessToken();
}
return $accessToken;
}
}
config文件:
<?php
return [
'app' => 'openwechat',
'name' => '企业名称',
'corpid' => 'xxxxx',
'agentid' => '1000002',
'secret' => 'xxxxxx',
'redirect_uri' => 'http://www.xxxx.com/api/login', //登录跳转url
'robotKey' => '693axxx6-7aoc-4bc4-97a0-0ec2sifa5aaa', //机器人Key
'toUser' => 'user1|user2', //多人用“|”分割
];
企微登录
企业微信的授权登录可大致分为:OAuth2.0授权和网页授权。这里主要记录网页登录授权功能的对接,以供下次参考!
官方文档参考:developer.work.weixin.qq.com/docum...
简要流程图:
OAuth2.0登录
- 【忽略】按需参考。OAuth2.0正常流程。通常是企微终端内部,小程序的授权登录
- 【核心】构建网页授权链接:【open.weixin.qq.com/connect/oauth2/...】
- 【snsapi_base:静默授权】可以通过此参数配合,实现业务系统在企微内的免密登录
Web登录
- 【配置】管理端后台创建一个具备“企业微信授权登录”能力的应用【企微管理后台-自建应用,可见范围设置为“全部”】
- 【配置】开启网页授权登录【企微管理后台-自建应用-企业微信授权登录-设置】。配置的授权回调域,必须与访问链接的域名完全一致!
- 【后端】按上图流程,首先构建“企业微信登录链接”,获取“code”【login.work.weixin.qq.com/wwlogin/s...】。注意:这里的配置的 redirect_uri 地址须带上协议头【http/https】
- 【前端】redirect_uri 说明,扫码/登录成功后,重定向到:redirect_uri?code=CODE&state=STATE
- 【后端】拿到code后,后端即可向企微认证消费code:【GET】qyapi.weixin.qq.com/cgi-bin/auth/g...,获取登录信息,生产登录状态,向前端颁发token
构建url参数说明:
参数 | 类型 | 必填 | 定义 | 说明 |
---|---|---|---|---|
login_type | string | 是 | 登录类型 | ServiceApp:服务商登录;CorpApp:企业自建/代开发应用登录 |
appid | string | 是 | 企业 CorpID或SuiteID | login_type为CorpApp时填企业 CorpID,ServiceApp填登录授权 SuiteID |
agentid | string | 否 | 应用 AgentID | 企业自建应用/服务商代开发应用 AgentID,当login_type=CorpApp时填写 |
redirect_uri | string | 是 | 登录成功重定向 url | 需进行 URLEncode。注意域名必须配置为可信域名【OAuth可信域名或者Web网页授权回调域名】 |
state | string | 否 | 登录 state | 保持请求和回调的状态,原样返回。可用于防止CSRF 攻击,可设置校验 |
lang | string | 否 | 语言类型 | zh:中文;en:英文。 |
核心代码:
<?php
namespace App\Service;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class OpenWeChatAuthService extends OpenWeChatService
{
/**
* 获取企业微信登录链接
* @return string
*/
public function getLoginUrl()
{
$queryData = [
'login_type' => 'CorpApp',
'appid' => $this->corpid,
'redirect_uri' => config('openwechat.redirect_uri'),
'agentid' => $this->agentid,
'state' => 'STATE',
'lang' => 'zh',
];
$url = 'https://login.work.weixin.qq.com/wwlogin/sso/login?' . http_build_query($queryData);
return $url;
}
/**
* 消费code,获取登录用户信息
* @param $code [授权链接登录后跳转自带的code]
* @return mixed [企业成员:userid、user_ticket,非企业成员:openid、external_userid]
* @throws \Exception
*/
public function getUserInfo($code)
{
$url = 'https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=' . $this->getAccessToken() . '&code=' . $code;
try {
$response = Http::get($url)->json();
} catch (\Exception $e) {
throw new \Exception('获取登录用户【/auth/getuserinfo】失败,请求失败:' . $url);
}
if (isset($response['errcode']) && $response['errcode'] <> 0) {
throw new \Exception('获取登录用户【/auth/getuserinfo】失败,响应:' . json_encode($response, JSON_UNESCAPED_UNICODE));
}
return $response;
}
/**
* 获取用户敏感信息
* @param $userTicket [self::getUserInfo => user_ticket]
* @return mixed
* @throws \Exception
*/
public function getUserDetail($userTicket)
{
$url = 'https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail?access_token=' . $this->getAccessToken();
$data = [
'user_ticket' => $userTicket
];
try {
$response = Http::post($url, $data)->json();
Log::info(__METHOD__, ['url' => $url, 'data' => $data]);
} catch (\Exception $e) {
throw new \Exception('获取用户敏感信息失败,url:' . $url . '|参数:' . json_encode($data, JSON_UNESCAPED_UNICODE));
}
if (isset($response['errcode']) && $response['errcode'] <> 0) {
throw new \Exception('获取用户敏感信息失败,响应:' . json_encode($response, JSON_UNESCAPED_UNICODE));
}
return $response;
}
}
备注说明
环境:php7.4 + laravel8
附:EasyWeChat 工具包,文档:easywechat.com/6.x/mini-app/utils....
本作品采用《CC 协议》,转载必须注明作者和本文链接
点赞,正需要这个 :+1:
learning
EasyWeChat一下就搞定了,花里胡哨
点赞, 点赞 mark