当前位置:网站首页>微信公众号网页授权
微信公众号网页授权
2022-07-04 03:32:00 【Cancri e】
整体流程
微信官方文档:网页授权 | 微信开放文档
前期准备 
在这里,我们不需要申请真的公众号,微信团队为广大的开发者提供了一个测试账号。该帐号无需公众账号,快速申请接口测试,直接体验和测试公众平台所有高级接口。地址:微信公众平台 ,扫描测试号二维码, 并关注公众号。我们将得到appID和appsecret(后续开发中将会用到)。
因为我们要与微信服务器进行交互,而我们开发的程序访问网址为127.0.0.1:8080,因此我们需要先将自己的访问地址暴露在公网上,这里我使用的是NATAPP。(注册需要实名验证)
官方网址:NATAPP-内网穿透 基于ngrok的国内高速内网映射工具。
内网穿透步骤
第一步:登录成功后在左侧 我的隧道 中选择 购买隧道,下图以免费隧道为例。
第二步:购买成功后在左侧 我的隧道 中选择 我的隧道,如下图所示。
第三步:显示成功后,下载NATAPP客户端。
第四步:双击 natapp.exe,在命令行输入 natapp -authtoken=xxx (其中,xxx为网页中我的隧道的authtoken),成功界面如下图所示。
红框内马赛克的地方就是你的公网上的地址。 (因为是免费隧道,该地址不固定,隔一段时间将会改变)。
第五步:将该地址去掉 http:// 填入 微信公众平台->网页服务->网页账号中。
微信公众平台测试号接口配置
URL中填写 微信服务器 访问开发程序的 接口地址,马赛克处为前面配置的公网地址;Token需要与代码中一致,这边我设置为 wxtoken 。
代码编写
项目结构
WeixinOauthController
@Controller
@RequestMapping("weixin")
public class WeixinOauthCotroller {
@RequestMapping("oauth")
public void oauth(HttpServletResponse response) throws IOException {
String path = MenuManager.REAL_URL + "weixin/invoke";
try {
path = URLEncoder.encode(path, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
"appid=" + MenuManager.APP_ID +
"&redirect_uri=" + path +
"&response_type=code" +
"&scope=snsapi_base" +
"&state=STATE" +
"#wechat_redirect";
response.sendRedirect(url);
}
@ResponseBody
@RequestMapping("invoke")
public JSONObject oauthInvoke(HttpServletRequest request) throws JSONException {
//获得code
String code = request.getParameter("code");
String state = request.getParameter("state");
//通过code换取网页授权access_token
//认证服务器
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid=" + MenuManager.APP_ID +
"&secret=" + MenuManager.APP_SECRET +
"&code=" + code +
"&grant_type=authorization_code";
//认证服务器 带着code发送请求 得到 access_token
JSONObject jsonObjectPost = new JSONObject(Send.sendPost(url));
System.out.println(jsonObjectPost);
String accessToken = jsonObjectPost.getString("access_token");
String openid = jsonObjectPost.getString("openid");
//带着openid和access_token 获取资源信息
String urlInfo = "https://api.weixin.qq.com/sns/userinfo?" +
"access_token=" + accessToken +
"&openid=" + openid +
"&lang=zh_CN";
JSONObject jsonObjectGet = new JSONObject(Send.sendGet(urlInfo));
System.out.println(jsonObjectGet);
System.out.println(jsonObjectGet.getString("nickname"));
return jsonObjectGet;
}
}
WxSignatureCheckController
@RestController
public class WxSignatureCheckController {
@Autowired
private WxSignatureCheckService wxSignatureCheckService;
@RequestMapping("/wxCheck")
public String wxSignatureCheck(
@RequestParam(value = "signature") String signature,
@RequestParam(value = "timestamp") String timestamp,
@RequestParam(value = "nonce") String nonce,
@RequestParam(value = "echostr") String echostr
){
return wxSignatureCheckService.wxSignatureCheck(signature, timestamp, nonce, echostr);
}
}
WxSignatureCheckService(token需要与微信公众平台上一致)
@Service
public class WxSignatureCheckService {
//token值必须和微信公众号中配置的完全一致!!!
private final String token = "wxtoken";
public String wxSignatureCheck(String signature, String timestamp, String nonce, String echostr) {
ArrayList<String> array = new ArrayList<String>();
array.add(signature);
array.add(timestamp);
array.add(nonce);
//排序
String sortString = sort(token, timestamp, nonce);
//加密
String mytoken = Decript.SHA1(sortString);
//校验签名
if (mytoken != null && mytoken != "" && mytoken.equals(signature)) {
System.out.println("签名校验通过。");
return echostr; //如果检验成功输出echostr,微信服务器接收到此输出,才会确认检验完成。
} else {
System.out.println("签名校验失败。");
return null;
}
}
/**
* 排序方法
* @param token
* @param timestamp
* @param nonce
* @return
*/
public static String sort(String token, String timestamp, String nonce) {
String[] strArray = { token, timestamp, nonce };
Arrays.sort(strArray);
StringBuilder sbuilder = new StringBuilder();
for (String str : strArray) {
sbuilder.append(str);
}
return sbuilder.toString();
}
}
Decript
/**
* 加密方法
*/
public class Decript {
public static String SHA1(String decript) {
try {
MessageDigest digest = MessageDigest
.getInstance("SHA-1");
digest.update(decript.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
// 字节数组转换为 十六进制 数
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
}
MenuManager(需要修改为自己的信息)
public class MenuManager {
public static final String APP_ID = 微信公众平台上的appID;
public static final String APP_SECRET = 微信公众平台上的appsecret;
public static final String REAL_URL = 公网地址(包含http://);
}
Send
public class Send {
/**
* 向指定 URL 发送POST方法的请求
* @param url 发送请求的 URL
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!" + e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
/**
* 向指定URL发送GET方法的请求
* @param url 发送请求的URL
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
}
结果
未制作前端界面,仅为控制台能输出用户信息。
边栏推荐
- static hostname; transient hostname; pretty hostname
- 2022 attached lifting scaffold worker (special type of construction work) free test questions and attached lifting scaffold worker (special type of construction work) examination papers 2022 attached
- Site favorites
- Command Execution Vulnerability - command execution - vulnerability sites - code injection - vulnerability exploitation - joint execution - bypass (spaces, keyword filtering, variable bypass) - two ex
- 基於.NetCore開發博客項目 StarBlog - (14) 實現主題切換功能
- Add IDM to Google browser
- Apple submitted the new MAC model to the regulatory database before the spring conference
- false sharing
- Problems and solutions of several concurrent scenarios of redis
- The difference between MCU serial communication and parallel communication and the understanding of UART
猜你喜欢
Don't disagree, this is the most powerful "language" of the Internet
Teach you how to optimize SQL
Development of digital collection trading platform development of digital collection platform
Lichuang EDA learning notes 14: PCB board canvas settings
How to use websocket to realize simple chat function in C #
Explain AI accelerator in detail: why is this the golden age of AI accelerator?
Fudan released its first review paper on the construction and application of multimodal knowledge atlas, comprehensively describing the existing mmkg technology system and progress
Backpropagation formula derivation [Li Hongyi deep learning version]
No clue about the data analysis report? After reading this introduction of smartbi, you will understand!
There is no need to authorize the automatic dream weaving collection plug-in for dream weaving collection
随机推荐
This function has none of DETERMINISTIC, NO SQL..... (you *might* want to use the less safe log_bin_t
Leecode 122. Zuijia timing of buying and selling stocks ②
[development team follows] API specification
7 * 24-hour business without interruption! Practice of applying multiple live landing in rookie villages
2022 registration examination for safety production management personnel of fireworks and firecracker production units and examination skills for safety production management personnel of fireworks an
Dare to climb here, you're not far from prison, reptile reverse actual combat case
Contest3145 - the 37th game of 2021 freshman individual training match_ 1: Origami
Experience summary of the 12th Blue Bridge Cup (written for the first time)
What is the difference between enterprise wechat applet and wechat applet
National standard gb28181 protocol platform easygbs fails to start after replacing MySQL database. How to deal with it?
JVM family -- heap analysis
The "two-way link" of pushing messages helps app quickly realize two-way communication capability
[UE4] parse JSON string
CUDA basic knowledge
Fudan released its first review paper on the construction and application of multimodal knowledge atlas, comprehensively describing the existing mmkg technology system and progress
2022 examination summary of quality controller - Equipment direction - general basis (quality controller) and examination questions and analysis of quality controller - Equipment direction - general b
Recursive structure
Summary of Chinese remainder theorem
Leetcode 110 balanced binary tree
Jenkins continuous integration environment construction V (Jenkins common construction triggers)