记录一下最近做的一个微信网页授权的例子

大概思路是,生成一个二维码,用户扫描二维码点击确认,进行网页授权。

首先申请一个测试公众号

https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

扫描二维码,就可以申请一个测试公众号,然后我们需要接口配置信息的地方修改成我们自己的服务器信息,如果没有服务器的话,就使用ngrok做一个内网穿透

然后在配置成内网穿透后的地址

在网页授权的地方修改一下二级域名

配置工作做好之后,我们只需要根据微信开发文档,来一步步获取我们需要的信息就可以了

直接贴上所有代码

import com.shanpu.wxsignin.constant.WxConstants;
import com.shanpu.wxsignin.utils.QRCodeUtil;
import com.shanpu.wxsignin.utils.Sha1Utils;
import net.sf.json.JSONObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;/*** @Classname WxSign* @Description TODO* @Date 2019/11/29 13:36* @Created by lijinghua*/
@RequestMapping(value="/wx")
@RestController
public class WxSign {private static final String TOKEN = "test";@GetMapping("/init")public String wxSign(String redirectUri, String openId, HttpServletResponse response, HttpServletRequest request ){String echostr = request.getParameter("echostr");System.out.println(echostr);return echostr;}/*** @Description 生成有回调地址的二维码* @param* @return java.lang.String* @Date 2019/12/2 14:09* @user*/@GetMapping("/getQRCode")public String getQRCode()throws Exception{String redirect_uri = WxConstants.REDIRECT_URI;String appid = WxConstants.APPID;String url = WxConstants.GET_CODE_URL.replace("APPID", appid).replace("REDIRECTURI", URLEncoder.encode(redirect_uri,"UTF-8"));String imgUrl = "D:/qrCode/dog";String returnUrl = "";try{returnUrl = QRCodeUtil.encode(url,imgUrl,true);}catch(Exception e){e.printStackTrace();}return returnUrl;}@GetMapping("/login")public String login(HttpServletResponse response, HttpServletRequest request )throws Exception{System.out.println("/login");String code = request.getParameter("code");Map<String, String> tokenAndOpenId = getAccessTokenAndOpenId(code);getUserInfo(tokenAndOpenId);return "";}private void getUserInfo(Map<String, String> tokenAndOpenId) throws Exception {String userUrl = WxConstants.USERINFO_URL.replace("ACCESS_TOKEN", tokenAndOpenId.get("accessToken")).replace("OPENID", tokenAndOpenId.get("openid"));JSONObject json = httpClient("GET", userUrl);System.out.println(json);}/*** @Description 通过code得到access_token* @param code* @return java.lang.String* @Date 2019/12/2 16:01* @user*/public Map<String,String> getAccessTokenAndOpenId(String code)throws Exception{//获取codeSystem.out.println(code);String appid = WxConstants.APPID;String appsecrt = WxConstants.APPSECRT;//通过code获取access_tokenString accessTokenUrl = WxConstants.ACCESS_TOKEN_URL.replace("CODE",code).replace("APPID",appid).replace("SECRET",appsecrt);// 发起GET请求获取access_tokenStringBuffer sb = new StringBuffer(accessTokenUrl);// 发送请求JSONObject json = httpClient("GET", sb.toString());Map<String,String> resultMap = new HashMap<>(2);String accessToken = json.getString("access_token");String openid = json.getString("openid");resultMap.put("accessToken",accessToken);resultMap.put("openid",openid);return resultMap;}public static void main(String[] args) {String redirect_uri = WxConstants.REDIRECT_URI;String appid = WxConstants.APPID;String url = WxConstants.GET_CODE_URL.replace("APPID", appid).replace("REDIRECTURI", redirect_uri);String imgUrl = "D:/qrCode/dog";try{String returnUrl = QRCodeUtil.encode(url,imgUrl,true);System.out.println(returnUrl);}catch(Exception e){e.printStackTrace();}}/*** @Description 发起http请求* @param requestMethod, requestUrl* @return net.sf.json.JSONObject* @Date 2019/12/2 16:29* @user*/public JSONObject httpClient(String requestMethod,String requestUrl)throws Exception{URL url = new URL(requestUrl);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod(requestMethod);BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));JSONObject json = new JSONObject();// 返回结果while ((in.read()) != -1) {String jsonMessage = "{"+in.readLine();json=JSONObject.fromObject(jsonMessage);if (null != json) {json.toString();}}in.close();System.out.println(json);return json;}
}
public class WxConstants {/*** //appId*/public static final String APPID = "";/*** appsecret*/public static final String APPSECRT = "";/*** //本地微信回调地址*/public static final String REDIRECT_URI = "http://93419d0b.ngrok.io/wx/login";/*** //获取code*/public static final String GET_CODE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECTURI&response_type=code&scope=snsapi_userinfo&state=123456789#wechat_redirect";/*** //获取access_token的URL*/public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";/*** //获取微信用户信息*/public static final String USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";/*** //不通过code获取access_token的URL*/public static final String NO_CODE_ACCESS_TOKEN_URL ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";}
/*** @Classname WxUser* @Description TODO* @Date 2019/12/2 16:15* @Created by lijinghua*/
public class WxUser {private String openid;private String nickname;private String sex;private String province;private String city;private String country;private String headimgurl;private String unionid;
}
package com.shanpu.wxsignin.utils;import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Random;/*** @Classname QRCodeUtil* @Description TODO* @Date 2019/11/29 15:41* @Created by lijinghua*/
public class QRCodeUtil {private static final String CHARSET = "utf-8";private static final String FORMAT_NAME = "JPG";// 二维码尺寸private static final int QRCODE_SIZE = 300;// LOGO宽度private static final int WIDTH = 60;// LOGO高度private static final int HEIGHT = 60;/*** 生成二维码* @param content   源内容* @param imgPath    生成二维码保存的路径* @param needCompress    是否要压缩* @return     返回二维码图片* @throws Exception*/private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {Hashtable hints = new Hashtable();hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);hints.put(EncodeHintType.CHARACTER_SET, CHARSET);hints.put(EncodeHintType.MARGIN, 1);BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,hints);int width = bitMatrix.getWidth();int height = bitMatrix.getHeight();BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);}}if (imgPath == null || "".equals(imgPath)) {return image;}// 插入图片QRCodeUtil.insertImage(image, imgPath, needCompress);return image;}/*** 在生成的二维码中插入图片* @param source* @param imgPath* @param needCompress* @throws Exception*/private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {File file = new File(imgPath);if (!file.exists()) {System.err.println("" + imgPath + "   该文件不存在!");return;}Image src = ImageIO.read(new File(imgPath));int width = src.getWidth(null);int height = src.getHeight(null);if (needCompress) { // 压缩LOGOif (width > WIDTH) {width = WIDTH;}if (height > HEIGHT) {height = HEIGHT;}Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics g = tag.getGraphics();g.drawImage(image, 0, 0, null); // 绘制缩小后的图g.dispose();src = image;}// 插入LOGOGraphics2D graph = source.createGraphics();int x = (QRCODE_SIZE - width) / 2;int y = (QRCODE_SIZE - height) / 2;graph.drawImage(src, x, y, width, height, null);Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);graph.setStroke(new BasicStroke(3f));graph.draw(shape);graph.dispose();}/*** 生成带logo二维码,并保存到磁盘* @param content* @param imgPath    logo图片* @param destPath* @param needCompress* @throws Exception*/public static String encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);mkdirs(destPath);/*** 生成随机文件名*/String file = new Random().nextInt(99999999) + ".jpg";ImageIO.write(image, FORMAT_NAME, new File(destPath + "/" + file));return imgPath+file;}public static void mkdirs(String destPath) {File file = new File(destPath);// 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir。(mkdir如果父目录不存在则会抛出异常)if (!file.exists() && !file.isDirectory()) {file.mkdirs();}}public static void encode(String content, String imgPath, String destPath) throws Exception {QRCodeUtil.encode(content, imgPath, destPath, false);}public static String encode(String content, String destPath, boolean needCompress) throws Exception {return QRCodeUtil.encode(content, null, destPath, needCompress);}public static void encode(String content, String destPath) throws Exception {QRCodeUtil.encode(content, null, destPath, false);}public static void encode(String content, String imgPath, OutputStream output, boolean needCompress)throws Exception {BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);ImageIO.write(image, FORMAT_NAME, output);}public static void encode(String content, OutputStream output) throws Exception {QRCodeUtil.encode(content, null, output, false);}/*** 从二维码中,解析数据* @param file 二维码图片文件* @return    返回从二维码中解析到的数据值* @throws Exception*/public static String decode(File file) throws Exception {BufferedImage image;image = ImageIO.read(file);if (image == null) {return null;}BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));Result result;Hashtable hints = new Hashtable();hints.put(DecodeHintType.CHARACTER_SET, CHARSET);result = new MultiFormatReader().decode(bitmap, hints);String resultStr = result.getText();return resultStr;}public static String decode(String path) throws Exception {return QRCodeUtil.decode(new File(path));}}
package com.shanpu.wxsignin.utils;import com.google.zxing.LuminanceSource;import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;/*** @Classname BufferedImageLuminanceSource* @Description TODO* @Date 2019/11/29 15:43* @Created by lijinghua*/
public class BufferedImageLuminanceSource extends LuminanceSource{private final BufferedImage image;private final int left;private final int top;public BufferedImageLuminanceSource(BufferedImage image) {this(image, 0, 0, image.getWidth(), image.getHeight());}public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height) {super(width, height);int sourceWidth = image.getWidth();int sourceHeight = image.getHeight();if (left + width > sourceWidth || top + height > sourceHeight) {throw new IllegalArgumentException("Crop rectangle does not fit within image data.");}for (int y = top; y < top + height; y++) {for (int x = left; x < left + width; x++) {if ((image.getRGB(x, y) & 0xFF000000) == 0) {image.setRGB(x, y, 0xFFFFFFFF); // = white}}}this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY);this.image.getGraphics().drawImage(image, 0, 0, null);this.left = left;this.top = top;}@Overridepublic byte[] getRow(int y, byte[] row) {if (y < 0 || y >= getHeight()) {throw new IllegalArgumentException("Requested row is outside the image: " + y);}int width = getWidth();if (row == null || row.length < width) {row = new byte[width];}image.getRaster().getDataElements(left, top + y, width, 1, row);return row;}@Overridepublic byte[] getMatrix() {int width = getWidth();int height = getHeight();int area = width * height;byte[] matrix = new byte[area];image.getRaster().getDataElements(left, top, width, height, matrix);return matrix;}@Overridepublic boolean isCropSupported() {return true;}public LuminanceSource crop(int left, int top, int width, int height) {return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height);}@Overridepublic boolean isRotateSupported() {return true;}@Overridepublic LuminanceSource rotateCounterClockwise() {int sourceWidth = image.getWidth();int sourceHeight = image.getHeight();AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth);BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY);Graphics2D g = rotatedImage.createGraphics();g.drawImage(image, transform, null);g.dispose();int width = getWidth();return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);}}

生产二维码使用的jar包

<dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.0</version></dependency><dependency><groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId><version>2.4</version><classifier>jdk15</classifier></dependency>

微信公众号网页授权记录相关推荐

  1. 微信公众号网页授权--前端获取code及用户信息(vue)

    前段时间开发微信公众号网页授权,虽然网上已经有很多关于这方面的博客或者教程,但是第一次开发还是遇到挺多坑的,以下分享一下我的踩坑填坑之路. 一.测试号相关配置 首先在你公司申请的测试号上配置好相关信息 ...

  2. 微信公众号网页授权--前端获取code及用户信息(vue)【简单详细版】

    嗨喽大家好,前段时间开发微信公众号网页授权,虽然网上已经有很多关于这方面的博客或者教程,但是第一次开发还是遇到挺多坑的,以下分享一下我的遇到的一些问题的见解,希望对你们有帮助. 一.测试号相关配置 首 ...

  3. 微信公众号网页授权思路解析及具体代码

    微信公众号网页授权思路解析及具体代码 微信开发文档 实现方式也是两种: 1.静默授权登录 授权登录以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静 ...

  4. 微信公众号网页授权,获取用户信息以及openid -- PHP后台

    微信公众号网页授权,获取用户信息以及openid 这几天做项目,想通过公众号的appid获取用户的openid就,然后在网上查资料,问朋友,最后找到了方法,就是这个网页授权. 起初一直很蒙,这个怎么弄 ...

  5. 微信公众号网页授权时序图

    微信公众号网页授权时序图 公众号网页授权时序图

  6. 微信公众号网页授权登录的超简单实现步骤

    微信开放平台为第三方移动程序提供分享.传播的接口, 使用户可将第三方程序的内容发布给好友或分享至朋友圈, 下面这篇文章主要给大家介绍了关于微信公众号网页授权登录的超简单实现方法, 需要的朋友可以参考下 ...

  7. 微信公众号网页授权40163问题【php】

    微信公众号网页授权40163问题 tp5为例,emmmm-一直报40163或40029问题,翻遍了各大网站都没找到合适我的办法. 如图: 解决之后如图: 因为重定向所以请求了两次code,所以一直报4 ...

  8. 微信公众号网页授权代码优化过程(一)

    2019独角兽企业重金招聘Python工程师标准>>> 第一次更新 写本系列博客的主要原因是,我在处理一个微信公众号项目时要做一个网页授权的操作(官方地址是https://mp.we ...

  9. php微信授权没有code返回,解决关于微信公众号网页授权获取code参数的问题

    解决关于微信公众号网页授权获取code参数的问题 发布时间:2018-07-24 23:21, 浏览次数:3327 , 标签: code * 在微信网页授权过程中,需要获取code参数,因为我用的是公 ...

最新文章

  1. 老张喝茶 教你同步异步 阻塞与非阻塞(转)
  2. 人人可用的AI大模型来了,“玩”TA还有奖金拿
  3. 职业生涯又一个转折点
  4. 牛X的web报表设计工具Grid++Report
  5. JavaScript社区开发者调查:服务端JS盛行 AngularJS使用者最多
  6. Matlab学习笔记:画图多重设置
  7. C++并发编程线程间共享数据std::future和sd::promise
  8. flink on yarn模式下释放flink占用yarn的资源
  9. 到现在了还不会Webpack?我帮你总结好了
  10. 小米羊城通余额不足服务器维护,再不怕羊城通余额不够了!地铁站现自助补票“神器”...
  11. 亚马逊 ai 解雇_解雇社区成员
  12. 构建 QC + QTP 自动化测试框架 2:QC 与 QTP 安装
  13. SecureCRT的安装破解
  14. 《子夜秋歌》赏析-(李白明月姑娘之六)
  15. 网易2016实习研发笔试
  16. word、wps图文复制一键粘贴到富文本编辑器
  17. 全国计算机图书销售订单记录,销售订单管理信息系统.doc
  18. 人工智能—语音识别技术发展史
  19. 2021高考辽宁英语成绩查询,2021年辽宁高考英语满分多少分?
  20. 2021-08-15 minikube在阿里云centos系统上的安装实践

热门文章

  1. 名称的秘密:Excel中隐藏着的名称空间
  2. 网友戏说电影公司片头动画
  3. 浏览器下载文件不全解决方法
  4. Python报错处理libpng warning: iCCP: cHRM chunk does not match sRGB
  5. 内网Gitlab如何拉取代码
  6. 服务器网站扩容一年1g价格,服务器网站扩容 一年1G价格
  7. arduino使用oled代码_【教程】在ESP32上使用E32433T LoRa模块
  8. 网站 502 解决方法
  9. transforms.Compose和transforms.ToTensor()
  10. 计算机管理服务修复,电脑提示“部署映像服务和管理工具错误87”的修复步骤...