springBoot vue实现微信登录

后台

引入需要的pom依赖包

<dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5</version>
</dependency>

写页面需要调用的接口

package com.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.demo.utils.HttpUtils;
import org.springframework.web.bind.annotation.*;
import java.net.URLEncoder;

/**
 * @author liudean
 * @date 2021/4/25 11:04
 */
@RestController
@RequestMapping("/user")
public class DemoController {

    /**
     * 获取配置文件的相应参数配置
     */
    private String appid= "";//微信开放平台生成的appid

    private String appsecret = "";//微信开放平台生成的appsecret

    private String http = "http://localhost/wxlogin";//回调地址,也就是页面的地址。localhost也就是我微信开放平台上的域名回调域地址,浏览器默认80 所以我域名就用的localhost,自己踩了很多坑,这个回调地址不能加端口,不然会出现redirect uri 参数错误


    /**
     * 生成微信登录二维码
     * 这里主要是去调用微信的接口,并配上自己认证应用的appid、secret以及回url,生成回调需要用到的url。需要注意,这里的回调url是用作接下来微信授权的关键。
     */
    @PostMapping(value = "/getWechatQrCode")
    public String getWechatQrCode() {
        try {
            String oauthUrl = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
            String redirect_uri = URLEncoder.encode(http, "utf-8");
            System.out.println("redirect_uri:" + redirect_uri);
            oauthUrl = oauthUrl.replace("APPID", appid).replace("REDIRECT_URI", redirect_uri).replace("SCOPE", "snsapi_login");
            return oauthUrl;
        } catch (Exception e) {
            System.out.println("二维码生成失败");
            return null;
        }
    }

    /**
     * 微信认证/微信扫二维码登录的回调方法
     * 根据code获取获取access_token和openId
     * 再根据access_token和openId获取用户信息
     */
    @PostMapping(value = "/wxCallBack")
    public JSONObject wxCallBack(@RequestParam(value = "code") String code){
        //获取access_token
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=" + appid +
                "&secret=" + appsecret +
                "&code=" + code +
                "&grant_type=authorization_code";
        JSONObject resultObject = HttpUtils.httpGet(url);

        //请求获取userInfo
        String infoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                "?access_token=" + resultObject.getString("access_token") +
                "&openid=" + resultObject.getString("openid") +
                "&lang=zh_CN";

        JSONObject resultInfo = HttpUtils.httpGet(infoUrl);

        //此时已获取到userInfo,再根据业务进行处理
        System.err.println("请求获取userInfo:" + resultInfo.toString());


        //做登录或注册操作,编写自己的业务
        //JSONObject jsonObject = new JSONObject();
        //jsonObject.put("openId",resultObject.getString("openid"));
        return resultInfo;
    }


	//用的也就上面这两个接口,下面这个微信认证授权用不到

    /**
     * 微信认证授权
     */
    @PostMapping(value = "/login")
    public String login(){
        String url ="https://open.weixin.qq.com/connect/oauth2/authorize" +
                "?appid=" + appid + "" +
                "&redirect_uri=" + http + "" +
                "&response_type=code" +
                "&scope=snsapi_userinfo" +
                "&state=STATE#wechat_redirect";
        return url;
    }
}

注意:上面代码中,用到了HttpUtils工具类,附下

package com.demo.utils;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * @author liudean
 * @date 2021/4/25 10:53
 */
public class HttpUtils {
    private static Logger logger = LoggerFactory.getLogger(HttpUtils.class);

    private static RequestConfig requestConfig = null;

    static {
        // 设置请求和传输超时时
        requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();
    }

    /**
     * post请求传输json参数
     *
     * @param url       url地址
     * @param jsonParam 参数
     * @return
     */
    public static JSONObject httpPost(String url, JSONObject jsonParam) {
        // post请求返回结果
        CloseableHttpClient httpClient = HttpClients.createDefault();
        JSONObject jsonResult = null;
        HttpPost httpPost = new HttpPost(url);
        // 设置请求和传输超时时请求
        httpPost.setConfig(requestConfig);
        try {
            System.out.println(jsonParam);
            if (null != jsonParam) {
                // 解决中文乱码问题
                StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/json");
                httpPost.setEntity(entity);
            }
            System.out.println(jsonParam);
            CloseableHttpResponse result = httpClient.execute(httpPost);
            // 请求发请求成功,并得到响应
            if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String str = "";
                try {
                    // 读取服务器返回过来的json字符串数
                    str = EntityUtils.toString(result.getEntity(), "utf-8");
                    // 把json字符串转换成json对象
                    jsonResult = JSONObject.parseObject(str);
                } catch (Exception e) {
                    logger.error("post请求提交失败:" + url, e);
                }
            }
        } catch (IOException e) {
            logger.error("post请求提交失败:" + url, e);
        } finally {
            httpPost.releaseConnection();
        }
        return jsonResult;
    }

    /**
     * post请求传输String参数 例如:name=Jack&sex=1&type=2
     * Content-type:application/x-www-form-urlencoded
     *
     * @param url      url地址
     * @param strParam 参数
     * @return
     */
    public static JSONObject httpPost(String url, String strParam) {
        // post请求返回结果
        CloseableHttpClient httpClient = HttpClients.createDefault();
        JSONObject jsonResult = null;
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        try {
            if (null != strParam) {
                // 解决中文乱码问题
                StringEntity entity = new StringEntity(strParam, "utf-8");
                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/x-www-form-urlencoded");
                httpPost.setEntity(entity);
            }
            CloseableHttpResponse result = httpClient.execute(httpPost);
            // 请求发宋成功,并得到响应
            if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String str = "";
                try {
                    // 读取服务器返回过来的json字符串数据
                    str = EntityUtils.toString(result.getEntity(), "utf-8");
                    // 把json字符串转换成json对象
                    jsonResult = JSONObject.parseObject(str);
                } catch (Exception e) {
                    logger.error("post请求提交失败:" + url, e);
                }
            }
        } catch (IOException e) {
            logger.error("post请求提交失败:" + url, e);
        } finally {
            httpPost.releaseConnection();
        }
        return jsonResult;
    }

    /**
     * 发送get请求
     *
     * @param url 路径
     * @return
     */
    public static JSONObject httpGet(String url) {
        // get请求返回结果
        JSONObject jsonResult = null;
        CloseableHttpClient client = HttpClients.createDefault();
        // 发送get请求
        HttpGet request = new HttpGet(url);
        request.setConfig(requestConfig);
        try {
            CloseableHttpResponse response = client.execute(request);

            // 请求发送成功,并得到响应
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 读取服务器返回过来的json字符串数组
                HttpEntity entity = response.getEntity();
                String strResult = EntityUtils.toString(entity, "utf-8");
                // 把json字符串转换成json对象
                jsonResult = JSONObject.parseObject(strResult);
            } else {
                logger.error("get请求提交失败:" + url);
            }
        } catch (IOException e) {
            logger.error("get请求提交失败:" + url, e);
        } finally {
            request.releaseConnection();
        }
        return jsonResult;
    }
}

前台

<template>
    <div>
      <el-row>
      <el-button type="success" @click="wxLogin" round>微信登陆</el-button>
    </el-row>
    </div>
</template>

<script>
export default {

  mounted(){
    console.log(this.$route.query);
    var code = this.$route.query.code
    if(code!=null){
      console.log(66666);
      //如果用户扫码了自动进行回调方法
      this.$axios.post('/user/wxCallBack?code='+this.$route.query.code)
      .then(res=>{
        //拿到用户信息
        console.log(res.data);
        if(res.data){
        	//用户扫描后页面跳转
          this.$router.push({name:'wxlogin',params:{info:res.data}})
        }
        
      })
    }
  },

  methods:{
    wxLogin() {
      this.$axios.post('/user/getWechatQrCode')
        .then(res=>{
          console.log(res);
          //后台生成的url
          window.location.href = res.data;
        })
        .catch(err=>{
          console.log(err);
        })
    },
  }
}
</script>

<style>

</style>

如有不明白的可联系我或者参考微信官方文档
https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

上一篇:实现跨域的N种方法


下一篇:Java RestTemplate 请求参数字符串中有大括号{}的请求正确方法