SpringBoot+Vue实现企业微信h5一键登录

前期准备

准备好企业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);
        


总结

以上就是今天要讲的内容,本文仅仅简单介绍了企业微信自建应用一键登录的使用,第一次发文有问题可在评论区指出谢谢

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值