Java实现微信公众号扫码登录

前言

1.首先,调用微信公众平台的OAuth2.0授权接口,获取用户的授权信息。具体的,在用户点击授权登录按钮时,向微信服务器发送请求,微信服务器会返回一个授权链接,用户点击授权链接后,微信服务器会跳转到你配置的回调地址,并带上授权码(code)。

2.使用授权码(code)调用微信公众平台的OAuth2.0接口,获取公众号的access_token。

3.使用access_token调用微信公众平台的用户信息接口,获取ticket。

4.在微信应用服务器端生成一个二维码用ticket换取,然后等候用户扫码。

5.用户扫码后回调获取到用户的openId,客户端可以通过openId来标识用户,并在之后的操作中使用。

上代码

一、导入Maven

<dependency>
    <groupId>com.github.binarywang</groupId>
    <artifactId>weixin-java-mp</artifactId>
    <version>4.3.0</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.20</version>
    <scope>compile</scope>
</dependency>

二、配置类

/**
 * @author My.Peng
 */
@Data
@Configuration
public class WechatConfig {

    /**
     * APPID
     */
    @Value("${tools.wechat.appid}")
    public String appid;

    @Value("${tools.wechat.secret}")
    public String appSecret;

}

三、工具类

/**
 * @author My.Peng
 */
public class JsonUtil {

    /**
     * 字符串Json格式转换为对象Map
     *
     * @param strJson {"username":"lp"}
     * @return 根据json转换为Map对象
     */
    public static Map<String, Object> jsonToMap(String strJson) {
        Map<String, Object> jsoMap = new HashMap<String, Object>();
        try {
            jsoMap = JSONObject.parseObject(strJson, Map.class);
        } catch (JSONException e) {
            System.out.println("json转换Map出错:" + e.getMessage());
        }
        return jsoMap;
    }

    /**
     * 字符串Json格式转换为对象Map
     *
     * @param strJson {"username":"lp"}
     * @return 根据json转换为Map对象
     */
    public static Map<String, String> jsonToMapString(String strJson) {
        Map<String, String> jsoMap = new HashMap<String, String>();
        try {
            jsoMap = JSONObject.parseObject(strJson, Map.class);
        } catch (JSONException e) {
            System.out.println("json转换Map出错:" + e.getMessage());
        }
        return jsoMap;
    }


    /**
     * 字符串Json 转换为对象List
     *
     * @param strJson [{"username":"lp"}]
     * @return 根据json转换List
     */
    public static List<Map<String, Object>> jsonToList(String strJson) {
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            list = JSONObject.parseObject(strJson, List.class);
        } catch (JSONException e) {
            System.out.println("json转换List出错:" + e.getMessage());
        }
        return list;
    }
}

四、上核心代码

/**
 * @author Mr.Peng
 */
@Slf4j
@Controller
@RequestMapping("/oauth2")
public class WechatLoginController {
    @Resource
    private WechatConfig wechatConfig;

    @GetMapping(value = "/wechat/login")
    @SneakyThrows
    public void wechatLoginPage(HttpServletResponse response, @RequestParam("ticket") String ticket) {
        log.info("请求二维码{}", ticket);
        String url = String.format(Constant.GET_QR_CODE_WX, ticket);
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpResponse resp = httpclient.execute(httpGet);
        byte[] data = EntityUtils.toByteArray(resp.getEntity());
        response.getOutputStream().write(data);
    }

    /**
     * 获取ticket
     *
     * @return ticket
     */
    @PostMapping("/wechat/ticket")
    @SneakyThrows
    @ResponseBody
    public Result<String> getTicket() {
        String accessToken = this.getAccessToken();

        String url = String.format(Constant.GET_QR_CODE, accessToken);
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Accept", "application/json");
        httpPost.addHeader("Content-type", "application/json; charset=utf-8");

        String param = new JSONObject()
                .put("expire_seconds", "120")
                .put("action_name", "QR_STR_SCENE")
                .put("action_info", new JSONObject()
                        .put("scene", "scene"))
                .toString();
        httpPost.setEntity(new StringEntity(param, "utf-8"));
        CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpResponse response = httpclient.execute(httpPost);
        String body = EntityUtils.toString(response.getEntity(), "utf-8");
        return Result.ok(JsonUtil.jsonToMapString(body).get("ticket"));
    }

    /**
     * 获取Access token
     *
     * @return access_token
     */
    @SneakyThrows
    public String getAccessToken() {
        String url = String.format(Constant.GET_ACCESS_TOKEN, wechatConfig.getAppid(), wechatConfig.getAppSecret());
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpResponse response = httpclient.execute(httpGet);

        String body = EntityUtils.toString(response.getEntity(), "utf-8");
        Map<String, String> stringStringMap = JsonUtil.jsonToMapString(body);
        if (stringStringMap.get("errmsg") != null) {
            log.error(stringStringMap.get("errmsg"));
        }
        return stringStringMap.get("access_token");
    }
}
/**
 * @author Mr.Peng
 */
@Slf4j
@RestController
@RequestMapping("/login/notify/wechat")
public class WechatLoginNotifyController {

    @Resource
    private UserService userService;

    @RequestMapping("/checkSign")
    public void checkSign(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        WxMpXmlMessage message = WxMpXmlMessage.fromXml(request.getInputStream());

        String userName = message.getToUser();
        String openid = message.getFromUser();

        assert openid != null;

        String content = "\uD83D\uDC4B Hey Guys I'm Li Peng. \n\n" +
                "\uD83D\uDC7E My Blog : https://lruri.com !";

        String replyMsg = "<xml>"
                + "<ToUserName><![CDATA[" + openid + "]]></ToUserName>"
                + "<FromUserName><![CDATA[" + userName + "]]></FromUserName>"
                + "<CreateTime>1531553112194</CreateTime>"
                + "<MsgType><![CDATA[text]]></MsgType>"
                + "<Content><![CDATA[" + content + "]]></Content>"
                + "<MsgId>1234567890123456</MsgId> "
                + " </xml>";
        log.info("用户扫码 | 关注 | openId:{},userName:{}", openid, userName);
        User buildUser = User.builder()
                .username(openid)
                .nickname("微信用户")
                .ticket(message.getTicket())
                .build();
        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
        wrapper.eq("username", message.getFromUser());
        userService.saveOrUpdate(buildUser, wrapper);
        response.getWriter().print(replyMsg);
    }

    /**
     * 验签token
     *
     * @param request
     * @return
     */
    //@RequestMapping("/checkSign")
    @SneakyThrows
    public String checkSign(HttpServletRequest request) {
        // Token
        String token = "token_li_peng";
        String[] params = new String[]{
                request.getParameter("timestamp"),
                request.getParameter("nonce"),
                token};
        Arrays.sort(params);
        String param = params[0] + params[1] + params[2];

        // 内容加密
        MessageDigest.getInstance("SHA-1")
                .digest(param.getBytes(StandardCharsets.UTF_8));

        // 接入服务器 验证Token签名
        return request.getParameter("echostr");
    }
}

成功

请添加图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PerryLes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值