前期准备
准备好企业id和应用Secret以及已备案好的域名(没有域名可用华为云的函数)
创建字符串静态类
/**
* 企业微信授权
*/
public interface qyWX{
String CORPID="";//企业id
String CORPSECRET="";//应用SECRET
}
配置企业微信可信域名
将下载好的文件放入nginx挂载的html中才会验证通过(服务器要绑定域名)
写好官方请求地址
// 获取企业微信 access_token
private final static String qy_access_token_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=CORPID&corpsecret=CORPSECRET";
// 获取企业微信 user_ticket
private final static String qy_user_ticket_url = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=TOKEN&code=CODE";
// 获取企业微信 user_info
private final static String qy_user_info_url = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail?access_token=TOKEN";
//读取员工
private final static String qy_get_user_url="https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=TOKEN&userid=USERID";
创建RestUtils用于组装url发送请求
package com.bngg.oa.utils;
import net.sf.json.JSONObject;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.*;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Objects;
@Configuration
public class RestUtils {
private static final RestTemplate restTemplate = new RestTemplate();
public static JSONObject get(String url, Map<String,String> urlParams){
return get(urlToUri(url,urlParams));
}
//在处理企业微信某些参数时有问题
public static JSONObject get(String url){
return get(URI.create(url));
}
private static JSONObject get(URI uri){
ResponseEntity<JSONObject> responseEntity =restTemplate.getForEntity(uri,JSONObject.class);
serverIsRight(responseEntity); //判断服务器返回状态码
return responseEntity.getBody();
}
public static JSONObject post(String url,Map<String,String> urlParams,JSONObject json){
//组装url
return post(urlToUri(url,urlParams),json);
}
public static JSONObject post(String url,JSONObject json){
//组装urL
return post(URI.create(url),json);
}
private static JSONObject post(URI uri,JSONObject json){
//组装url
//设置提交json格式数据
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<JSONObject> request = new HttpEntity(json, headers);
ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(uri,request,JSONObject.class);
serverIsRight(responseEntity); //判断服务器返回状态码
return responseEntity.getBody();
}
private static URI urlToUri(String url,Map<String,String> urlParams){
//设置提交json格式数据
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url);
for(Map.Entry<String,String> entry : urlParams.entrySet()) {
uriBuilder.queryParam((String)entry.getKey(), (String) entry.getValue()) ;
}
return uriBuilder.build(true).toUri();
}
public static JSONObject upload(String url, MultiValueMap formParams){
//设置表单提交
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(formParams, headers);
ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(url,request,JSONObject.class);
serverIsRight(responseEntity); //判断服务器返回状态码
return responseEntity.getBody();
}
public static String download(String url,String targetPath) throws IOException {
ResponseEntity<byte[]> rsp = restTemplate.getForEntity(url, byte[].class);
if(rsp.getStatusCode() != HttpStatus.OK){
System.out.println("文件下载请求结果状态码:" + rsp.getStatusCode());
}
// 将下载下来的文件内容保存到本地
Files.write(Paths.get(targetPath), Objects.requireNonNull(rsp.getBody()));
return targetPath;
}
public static byte[] dowload(String url){
ResponseEntity<byte[]> rsp = restTemplate.getForEntity(url, byte[].class);
return rsp.getBody();
}
private static void serverIsRight(ResponseEntity responseEntity){
if(responseEntity.getStatusCodeValue()==200){
// System.out.println("服务器请求成功:{}"+responseEntity.getStatusCodeValue());
}else {
System.out.println("服务器请求异常:{}"+responseEntity.getStatusCodeValue());
}
}
}
一、获取企业微信 access_token
如果报错就去企业微信配置可信ip,IP会跟随报错返回出来,如果在本地运行ip随时会变需重新添加
// 获取凭证信息
public String getAccessToken() {
String result = "";
String requestURL = qy_access_token_url.replace("CORPID", CommonConstants.qyWX.CORPID).replace( "CORPSECRET", CommonConstants.qyWX.CORPSECRET);
Map response = RestUtils.get(requestURL);
//获取错误日志
if (response.containsKey("errcode") && (Integer) response.get("errcode") != 0) {
Logger logger = null;
logger.error(response.toString());
} else {
result = (String) response.get("access_token");
}
return result;
}
二、获取code
1.vue前端配置请求地址
wxLogin2(){
Toast.loading({
message: '加载中...',
forbidClick: true,
});
const appid = ''; // 企业 ID
const redirect_uri = ''; // 授权后重定向的回调链接地址
const scope = ''; // 授权类型,snsapi_base 表示静默授权,snsapi_userinfo 表示用户授权
const agentid=''//应用id
const state = 'STATE'; // 可选参数,用于保持请求和回调的状态,防止 CSRF 攻击
// 构造授权链接
const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${encodeURIComponent(redirect_uri)}&response_type=code&scope=${scope}&agentid=${agentid}&state=${state}#wechat_redirect`;
// 打开授权链接
window.location.href = authUrl;
},
2.vue获取地址栏的code
mounted() {
// 获取URL中的参数
const urlParams = new URLSearchParams(window.location.search);
// 获取code参数的值
this.code = urlParams.get('code');
if(null !==this.code && undefined !== this.code && '' !== this.code ){
Toast.loading({
message: '加载中...',
forbidClick: true,
});
//调用登录接口传入code
}
},
三、获取访问用户身份
拿到用户的
user_ticket
//获取访问用户身份
public JSONObject getUserTicket(String accessToken, String code) {
String result = "";
String requestURL = qy_user_ticket_url.replace("TOKEN", accessToken).replace( "CODE", code);
Map response = RestUtils.get(requestURL);
//获取错误日志
if (response.containsKey("errcode") && (Integer) response.get("errcode") != 0) {
Logger logger = null;
throw new BlsException(CommonError.QUERY_ERROR,"网络出了点小差!请刷新");
// logger.error(response.toString());
} else {
result = (String) response.get("user_ticket");
}
Map<String,String> map=new HashMap<>();
map.put("user_ticket",result);
JSONObject jsonObject=JSONObject.fromObject(map);
re
四、获取用户敏感信息
这里拿不到用户的真实姓名只能拿到拼音
//获取用户敏感信息
public Map getUserInfo(String accessToken,JSONObject userTicket) {
String requestURL = qy_user_info_url.replace("TOKEN", accessToken);
Map response = RestUtils.post(requestURL,userTicket);
//获取错误日志
if (response.containsKey("errcode") && (Integer) response.get("errcode") != 0) {
Logger logger = null;
logger.error(response.toString());
}
return response;
}
五、读取员工
//读取员工
public Map readUser(String accessToken,String userid) {
String requestURL = qy_get_user_url.replace("TOKEN", accessToken).replace( "USERID", userid);;
Map response = RestUtils.get(requestURL);
//获取错误日志
if (response.containsKey("errcode") && (Integer) response.get("errcode") != 0) {
Logger logger = null;
logger.error(response.toString());
}
return response;
}
六、存储用户的信息并登录
我这里的R用来封装返回给前端的参数,将用户信息存储后直接调用登录接口即可一键登录
,如果没有备案域名使用华为云函数的话需要在postman中手动添加code来测试
@PostMapping("/qyWxLogin/{code}")
public R<PDALoginResVo> qyWxLogin(@PathVariable String code,HttpServletRequest request){
String accessToken = commonController.getAccessToken();
JSONObject userTicket = commonController.getUserTicket(accessToken, code);
Map userInfo = commonController.getUserInfo(accessToken, userTicket);
Map userid = commonController.readUser(accessToken, String.valueOf(userInfo.get("userid")));
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
User user =new User();
user.setUsername(String.valueOf(userInfo.get("userid")));
user.setNickname(String.valueOf(userid.get("name")));
user.setPassword(passwordEncoder.encode(String.valueOf(userInfo.get("mobile"))));
user.setMobile(String.valueOf(userInfo.get("mobile")));
user.setAvatar(String.valueOf(userInfo.get("avatar")));
user.setBizMail(String.valueOf(userInfo.get("biz_mail")));
//判断当前用户是否已经创建
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
queryWrapper.eq(User.MOBILE,user.getMobile());
User one = userService.getOne(queryWrapper);
if(null==one){
userService.save(user);
}
AdminLoginVo adminLoginVo=new AdminLoginVo();
adminLoginVo.setUsername(user.getUsername());
adminLoginVo.setPassword(user.getMobile());
R<PDALoginResVo> login = this.login(adminLoginVo, request);
总结
以上就是今天要讲的内容,本文仅仅简单介绍了企业微信自建应用一键登录的使用,第一次发文有问题可在评论区指出谢谢