微信配置文件

# 微信开放平台 appidwx.open.app-id=你的appid# 微信开放平台 appsecretwx.open.app-secret=你的secret# 微信开放平台 重定向urlwx.open.redirect-uri=重定向url/api/user/wx/callback

配置类

package com.atguigu.yygh.user.utils;import lombok.Data;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;@Configuration@PropertySource("classpath:wx.properties")@ConfigurationProperties(prefix = "wx.open")@Datapublic class ConstantProperties {    private String appId;    private String appSecret;    private String redirectUri;}

前端请求方法

 //切换微信登录    weixinLogin() {      this.dialogAtrr.showLoginType = 'weixin'      user.getQRCodeParams().then((response) =>{        new WxLogin({          //true:手机单击确认后可以在iframe内跳转到redirecturl        //false :手机单击确认登录后可以在top window 跳转到redirecturl            self_redirect: false,            id: 'weixinLogin', // 显示二维码的容器id            appid: response.data.appid,             scope: response.data.scope,             redirect_uri: response.data.redirectUri,            state: response.data.state,             style: 'black', // 提供"black"、"white"可选。二维码的样式            href: '', // 外部css文件url,需要https        })       })    },

前端api

 //获得微信登录二维码的相关参数  getQRCodeParams(){    return request({      url : `/api/user/wx/getQRCodeParams`,      method : `get`    })  },

生成二维码以及回调函数

api文档:网站应用微信登录开发指南

package com.atguigu.yygh.user.controller.api;import com.atguigu.yygh.common.exception.YyghException;import com.atguigu.yygh.common.result.R;import com.atguigu.yygh.common.result.ResultCode;import com.atguigu.yygh.common.utils.JwtHelper;import com.atguigu.yygh.model.user.UserInfo;import com.atguigu.yygh.user.service.UserInfoService;import com.atguigu.yygh.user.utils.ConstantProperties;import com.atguigu.yygh.user.utils.HttpClientUtils;import com.google.gson.Gson;import com.sun.org.apache.regexp.internal.RE;import io.swagger.annotations.Api;import lombok.extern.slf4j.Slf4j;import org.apache.http.client.utils.URLEncodedUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import sun.net.util.URLUtil;import javax.net.ssl.HttpsURLConnection;import javax.servlet.http.HttpSession;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import java.util.HashMap;import java.util.UUID;@Api(tags = "微信扫码登录")@Controller //注意这里没有配置@restcontroller@RequestMapping("/api/user/wx")@Slf4jpublic class ApiWxController {    @Autowired    private ConstantProperties constantProperties;    @Autowired    private UserInfoService userInfoService;    /**     * 方法一: 在新的页面打开显示二维码     */    @GetMapping("/getQRCodeUrl")    public String getQRCodeUrl(HttpSession session){        try {            //处理回调url            String redirectUrl = URLEncoder.encode(constantProperties.getRedirectUri(), "UTF-8");            //处理state :生成随机数,存入session            String state = UUID.randomUUID().toString();            log.info("生成的state = "+ state);            session.setAttribute("wx_open_state",state);            //要重定向的地址            String qrcUrl = "https://open.weixin.qq.com/connect/qrconnect" +                    "?appid=" + constantProperties.getAppId() +                    "&redirect_uri=" + redirectUrl +                    "&response_type=code" +                    "&scope=snsapi_login" +                    "&state=" + state +                    "#wechat_redirect";            return "redirect:" + qrcUrl;        } catch (UnsupportedEncodingException e) {            throw new YyghException(ResultCode.ERROR,"生成二维码错误");        }    }    /**     * 在内嵌窗口打开     * @param session     * @return     */    @GetMapping("/getQRCodeParams")    @ResponseBody    public R getQRCodeParams(HttpSession session){        try {            String redirectUrl = URLEncoder.encode(constantProperties.getRedirectUri(), "UTF-8");            String state = UUID.randomUUID().toString();            log.info("生成的state : "+ state);            session.setAttribute("wx_open_state",state);            //组装好返回给前端的数据            HashMap map = new HashMap();            map.put("appid",constantProperties.getAppId());            map.put("redirectUri",redirectUrl);            map.put("scope","snsapi_login");            map.put("state",state);            return R.ok().data(map);        } catch (UnsupportedEncodingException e) {            throw new YyghException(ResultCode.ERROR,"生成二维码错误");        }    }    /**     * 回调函数     */    @GetMapping("/callback")    public String callback(String code, String state, HttpSession session)  {        try {            String sessionState = (String)session.getAttribute("wx_open_state");            //判空操作            if(StringUtils.isEmpty(code) || StringUtils.isEmpty(state) || !state.equals(sessionState)){                throw new YyghException(ResultCode.ERROR,"回调参数错误");            }            //向微信发送请求,请求获得access_tokens            String accessTokenUrl ="https://api.weixin.qq.com/sns/oauth2/access_token" +                    "?appid=" + constantProperties.getAppId() +                    "&secret=" + constantProperties.getAppSecret() +                    "&code=" + code +                    "&grant_type=authorization_code";            //使用httpclient发送请求            String accessTokenInfo = HttpClientUtils.get(accessTokenUrl);            //将json'转换成map 获取其中的errcode键值 ,来判断相应的成功与否            Gson gson = new Gson();            HashMap accessTokenInfoMap = gson.fromJson(accessTokenInfo, HashMap.class);            //通过错误码是否存在来判断响应是否成功            if(accessTokenInfoMap.get("errcode") !=null ){ //errcode只要存在就说明有错误                throw new YyghException(ResultCode.ERROR,"获取access_token失败");            }            //微信获取access_token成功            String openid = (String) accessTokenInfoMap.get("openid");            String accessToken = (String) accessTokenInfoMap.get("access_token");            //根据openid判断数据库中的数据是否存在            UserInfo  userInfo= userInfoService.selectWxInfoByOpenId(openid);            if(userInfo==null){                //用户不存在则进行注册操作                //向微信的资源服务器发送请求,获得当前用户的信息                String userInfoUrl ="https://api.weixin.qq.com/sns/userinfo" +                        "?access_token=" + accessToken +                        "&openid=" + openid;                String userInfResult = HttpClientUtils.get(userInfoUrl);                HashMap userInfResultMap = gson.fromJson(userInfResult, HashMap.class);                //判断响应是否失败,同上                //通过错误码是否存在来判断响应是否成功                if(accessTokenInfoMap.get("errcode") !=null ){ //errcode只要存在就说明有错误                    throw new YyghException(ResultCode.ERROR,"获取用户信息失败");                }                //解析用户信息                String nickname =(String) userInfResultMap.get("nickname");                //用户注册(添加)                 userInfo = new UserInfo();                 userInfo.setName(nickname);                 userInfo.setNickName(nickname);                 userInfo.setOpenid(openid);                 userInfoService.save(userInfo);            }else {                //用户存在则只需判断用户状态是否可用                if(userInfo.getStatus() == 0){                    throw new YyghException(ResultCode.ERROR,"用户已被锁定");                }            }            //生成jwt字符串            String token = JwtHelper.createToken(userInfo.getId(), userInfo.getName());            //跳转到前端页面            return "redirect:http://localhost:3000/" +                    "?token=" + token +                    "&name=" + URLEncoder.encode(userInfo.getName(), "utf-8") +                    "&openid=" + openid +                    "&phone=" + userInfo.getPhone() ;        } catch (Exception e) {            throw new YyghException(ResultCode.ERROR,"微信登录失败",e);        }    }}