网页授权登录
前言
企业微信提供了OAuth的授权登录方式,可以让从企业微信终端打开的网页获取成员的身份信息,从而免去登录的环节。
企业应用中的URL链接(包括自定义菜单或者消息中的链接),均可通过OAuth2.0验证接口来获取成员的UserId身份信息。
一、构造网页授权链接
如果企业需要在打开的网页里面携带用户的身份信息,第一步需要构造如下的链接来获取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
参数说明:
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 企业的CorpID |
redirect_uri | 是 | 授权后重定向的回调链接地址,请使用urlencode对链接进行处理 |
response_type | 是 | 返回类型,此时固定为:code |
scope | 是 | 应用授权作用域。snsapi_base:静默授权,可获取成员的基础信息(UserId与DeviceId);snsapi_privateinfo:手动授权,可获取成员的详细信息,包含头像、二维码等敏感信息。 |
state | 否 | 重定向后会带上state参数,企业可以填写a-zA-Z0-9的参数值,长度不可超过128个字节 |
agentid | 是 | 应用agentid,snsapi_privateinfo时必填 |
#wechat_redirect | 是 | 终端使用此参数判断是否需要带上身份信息 |
员工点击后,页面将跳转至 redirect_uri?code=CODE&state=STATE,企业可根据code参数获得员工的userid。code长度最大为512字节。
实现代码:
String redirectUri = "需要的重定向地址";
String wysqlj = "https://open.weixin.qq.com/connect/oauth2/authorize";
String basePath = "C:\\tu\\";
String bgtuPath = "C:\\tu\\bg\\";
String appid = "企业的CorpID";
String status = "自定义参数";
//重定向地址,需要带上会议室id
String redirect_uri = URLEncoder.encode(redirectUri);
//生成二维码海报
String url = wysqlj + "?appid=" + appid + "&redirect_uri=" + redirect_uri + "&response_type=code&scope=snsapi_base&state="+status+"#wechat_redirect";
String path = basePath + System.currentTimeMillis() + ".png";
File filea = QrCodeUtil.generate(url,
QrConfig.create().setImg(bgtuPath+"logo.png"), //附带logo
FileUtil.file(path)//写出到的文件
);
会生成一个二维码,员工扫描二维码之后,页面将跳转至重定向的地址 redirect_uri?code=CODE&state=STATE,重定向地址回携带code参数,还有自定义的参数
注意,构造OAuth2链接中参数的redirect_uri是经过UrlEncode的
二、获取访问用户身份
该接口用于根据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分钟未被使用自动过期。 |
实现代码:
/**
* 获取访问用户身份
* @param identityUserInfoDTO
* @return
*/
@Override
public Map<String,Object> getUserInfo(String code) {
String accessToken = "调用接口凭证,access_token";
String url = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=ACCESS_TOKEN&code=CODE";
url = url.replace("ACCESS_TOKEN",accessToken).replace("CODE",code);
String res = HttpRequest.get(url).execute().body();
JSONObject jsonObject = JSON.parseObject(res);
log.info("从企微接口:{}\n获取访问用户身份结果:{}",url,res);
return MapUtil.jsonToResult(jsonObject);
}
返回说明:
a) 当用户为企业成员时(无论是否在应用可见范围之内)返回示例如下:
{
"errcode": 0,
"errmsg": "ok",
"userid":"USERID",
"user_ticket": "USER_TICKET"
}
字段说明:
参数 | 说明 |
---|---|
errcode | 返回码 |
errmsg | 对返回码的文本描述内容 |
userid | 成员UserID。若需要获得用户详情信息,可调用通讯录接口:读取成员。如果是互联企业/企业互联/上下游,则返回的UserId格式如:CorpId/userid |
user_ticket | 成员票据,最大为512字节,有效期为1800s。scope为snsapi_privateinfo,且用户在应用可见范围之内时返回此参数。后续利用该参数可以获取用户信息或敏感信息,参见"获取访问用户敏感信息"。暂时不支持上下游或/企业互联场景 |
b) 非企业成员时,返回示例如下:
{
"errcode": 0,
"errmsg": "ok",
"openid":"OPENID",
"external_userid":"EXTERNAL_USERID"
}
字段说明:
参数 | 说明 |
---|---|
errcode | 返回码 |
errmsg | 对返回码的文本描述内容 |
openid | 非企业成员的标识,对当前企业唯一。不超过64字节 |
external_userid | 外部联系人id,当且仅当用户是企业的客户,且跟进人在应用的可见范围内时返回。如果是第三方应用调用,针对同一个客户,同一个服务商不同应用获取到的id相同 |
三、获取访问用户敏感信息
自建应用与代开发应用可通过该接口获取成员授权的敏感字段
请求方式:POST(HTTPS)
请求地址:
https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail?access_token=ACCESS_TOKEN
请求体示例:
{
"user_ticket": "USER_TICKET"
}
参数说明:
参数 | 是否必须 | 说明 |
---|---|---|
access_token | 是 | 调用接口凭证 |
user_ticket | 是 | 成员票据 |
权限说明:
成员必须在应用的可见范围内。
实现代码:
/**
* 获取访问用户敏感信息
* @param identityUserDetailDTO
* @return
*/
@Override
public Map<String,Object> getUserDetail(String user_ticket) {
String accessToken = "调用接口凭证,access_token";
String url = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail?access_token=ACCESS_TOKEN";
url = url.replace("ACCESS_TOKEN",accessToken);
JSONObject json = new JSONObject();
json.put("user_ticket",user_ticket);
String res = HttpRequest.post(url).body(json.toJSONString()).execute().body();
JSONObject jsonObject = JSON.parseObject(res);
log.info("从企微接口:{}\n获取访问用户敏感信息结果:{}",url,res);
return MapUtil.jsonToResult(jsonObject);
}
返回结果:
{
"errcode": 0,
"errmsg": "ok",
"userid":"lisi",
"gender":"1",
"avatar":"http://shp.qpic.cn/bizmp/xxxxxxxxxxx/0",
"qr_code":"https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=vcfc13b01dfs78e981c",
"mobile": "13800000000",
"email": "zhangsan@gzdev.com",
"biz_mail":"zhangsan@qyycs2.wecom.work",
"address": "广州市海珠区新港中路"
}
参数说明:
参数 | 说明 |
---|---|
errcode | 返回码 |
errmsg | 对返回码的文本描述内容 |
userid | 成员UserID |
gender | 性别。0表示未定义,1表示男性,2表示女性。仅在用户同意snsapi_privateinfo授权时返回真实值,否则返回0. |
avatar | 头像url。仅在用户同意snsapi_privateinfo授权时返回 |
qr_code | 员工个人二维码(扫描可添加为外部联系人),仅在用户同意snsapi_privateinfo授权时返回 |
mobile | 手机,仅在用户同意snsapi_privateinfo授权时返回,第三方应用不可获取 |
邮箱,仅在用户同意snsapi_privateinfo授权时返回,第三方应用不可获取 | |
biz_mail | 企业邮箱,仅在用户同意snsapi_privateinfo授权时返回,第三方应用不可获取 |
address | 仅在用户同意snsapi_privateinfo授权时返回,第三方应用不可获取 |
注意:
对于自建应用与代开发应用,敏感字段需要管理员在应用详情里选择,且成员oauth2授权时确认后才返回。敏感字段包括:性别、头像、员工个人二维码、手机、邮箱、企业邮箱、地址。