流程
1.1 流程图
1.2 流程步骤
整体流程:
1.发出来的链接直接填写应用前端的链接
2.用户点击连接会跳到你的前端页面地址,如果你的页面有用户信息,则表示用户已经登录
3.如果没有用户信息,则请求你的应用后端的接口获取企业微信授权登录入口
4.获取到后前端告诉企业微信客户端重定向,企业微信客户端会重定向到企业微信服务端
5.企业微信服务端会携带code并重定向到你指定的回调地址,假设设置成前端地址。
6.前端地址获取到code后请求应用后端获取业务token
7.获取到后存入cookie即可,下次携带业务token到请求头上请求即可。
后端流程:
1.如果access_token过期,则先获取access_token(携带参数企业id和应用id),获取到后需要缓存,默认过期时间为两个小时(禁止频繁获取)
2.携带access_token和前端传递的code获取userTicket
3.携带access_token和userTicket获取用户详细信息(手机号等)
4.通过用户信息生成业务token
5.返回业务token给前端
1.3 操作配置
自建应用:
配置自己前端的可信域名和后端的可信ip:
设置通讯录:
开启通讯录api和设置后端ip:
1.4 相关参数
#企业微信授权登录入口 baseUrl
https://open.weixin.qq.com/connect/oauth2/authorize
#企业微信获取用户信息 baseUrl
https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo
#企业微信获取用户详细信息 baseUrl
https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail
#企业微信获取access_token baseUrl
https://qyapi.weixin.qq.com/cgi-bin/gettoken
#企业id
cropid=wwcb71ddb9a2d75462
#授权码模式
responseType=code
#授权范围
scope=snsapi_privateinfo
#企业微信授权标志
flag=#wechat_redirect
#自建应用secret
cropSecret=R2tC8Qx8sXr-rjMCJ7tyzR-KsHLZbK71ar9qLIhoLCA
#自建应用agentId
agentId=1000002
企业id:
自建应用agentId和secret:
1.5 相关请求
1.企业微信授权登录请求
假定当前企业CorpID:wxCorpId
访问链接:http://api.3dept.com/cgi-bin/query?action=get
生成的链接:
GET ttps://open.weixin.qq.com/connect/oauth2/authorize?appid=wxCorpId&redirect_uri=http%3a%2f%2fapi.3dept.com%2fcgi-bin%2fquery%3faction%3dget&response_type=code&scope=snsapi_privateinfo&agentid=AGENTID&state=#wechat_redirect
2.获取企业微信access_token请求
GET https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
3.获取企业微信用户信息请求
GET https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
4.获取企业微信用户详细信息请求
POST https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail?access_token=ACCESS_TOKEN
请求体:
{
"user_ticket":""
}
至此即可拿到用户手机号等信息
关键代码
//生成企业微信授权登录入口url
public WeChatVO getWeChatUrl(String frontUrl){
WeChatVO weChatVO = new WeChatVO();
try {
weChatVO.setWeChatUrl(generateWeChatOauth2Url(frontUrl));
} catch (UnsupportedEncodingException e) {
log.error(e.getMessage(),e);
}
return weChatVO;
}
//code生成业务token
public WeChatVO exchangeCode(String code,String state){
WeChatVO weChatVO = new WeChatVO();
if(StringUtils.isBlank(code)){
return weChatVO;
}
//1.校验access_token是否过期,如果过期重新获取
String redisWeChatAccessToken = (String) redisUtils.get(wechatRedisPrefix + WeChatParamConstant.ACCESS_TOKEN);
if(StringUtils.isBlank(redisWeChatAccessToken)) {
WeChatUserInfo webChatToken = obtainAccessToken();
String accessToken = webChatToken.getAccess_token();
Integer expiresIn = webChatToken.getExpires_in();
//将accessToken存入redis
redisUtils.set(wechatRedisPrefix+WeChatParamConstant.ACCESS_TOKEN,accessToken,expiresIn, TimeUnit.SECONDS);
redisWeChatAccessToken = accessToken;
}
//2.携带accessToken和code查询用户信息
WeChatUserInfo weChatUserInfo = obtainUserTicket(redisWeChatAccessToken,code);
String userTicket = weChatUserInfo.getUser_ticket();
String errMsg = weChatUserInfo.getErrmsg();
Integer errCode = weChatUserInfo.getErrcode();
if(errCode == null){
throw new BizGalaxyException(500,errMsg);
}
if(errCode != 0){
log.error("errCode:{},errMsg:{}",errCode,errMsg);
if(errCode == 42001){
//2.1 accessToken过期,重新查询accessToken
WeChatUserInfo weChatUser = obtainAccessToken();
String accessToken = weChatUser.getAccess_token();
Integer expiresIn = weChatUser.getExpires_in();
//2.2 将accessToken存入redis
redisUtils.set(wechatRedisPrefix+WeChatParamConstant.ACCESS_TOKEN,accessToken,expiresIn, TimeUnit.SECONDS);
}
throw new BizGalaxyException(errCode,errMsg);
}
//3.携带accessToken和userTicket查询用户详细信息
WeChatUserInfo weChatUserDetail = obtainUserDetail(redisWeChatAccessToken,userTicket);
String mobile = weChatUserDetail.getMobile();
log.info("mobile:{}",mobile);
//4.通过用户详细信息查询到自己系统用户信息
TSysUserEntity user = tSysUserMapper.selectByPhone(mobile);
if(ObjectUtils.isEmpty(user)){
throw new BizGalaxyException(CodeMsg.CODE_100001002);
}
//5.生成自己系统的业务token
String token = LoginManager.login(new UserVisitor(user.getId(), user.getUserType()));
log.info("token:{}",token);
weChatVO.setJwtToken(token);
return weChatVO;
}