【记录】网页获取微信授权

场景:在手机端用微信回答问卷时,客户想要通过微信获取用户信息

使用:SpringBoot、有域名的服务器(https://damionew.top)、微信公众平台测试号(带链接)、文档

开发过程:

1-申请微信公众平台测试号并完成配置

测试号信息appID 和 appsecret 是平台自动生成的

接口配置信息暂时无需填写

域名不要带https等

测试号二维码用于添加测试账号,只有列表中的用户才能使用,否则将提示无权限

任务目标

修改处填写域名,注意不要带https!

2-编写代码

项目结构

pom文件,主要是HTTPClient 和 Tomcat

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.3.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.test</groupId>
	<artifactId>weChatAuth</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>weChatAuth</name>
	<packaging>war</packaging>
	<description>微信授权</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency> 
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
		    <groupId>org.apache.httpcomponents</groupId>
		    <artifactId>httpclient</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<!-- tomcat的支持.-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
		<dependency>
        	<groupId>com.alibaba</groupId>
        	<artifactId>fastjson</artifactId>
        	<version>1.2.47</version>
        </dependency>
        <!-- 热启动 -->
		<dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-devtools</artifactId>  
            <scope>provided</scope>  
            <optional>true</optional>  
		</dependency>
		<dependency>
		    <groupId>log4j</groupId>
		    <artifactId>log4j</artifactId>
		    <version>1.2.17</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>wx</finalName>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
		<resources>
			<resource>
				<directory>src/main/java</directory>
				<includes>
					<include>**/*.dat</include>
				</includes>
				<filtering>false</filtering>
			</resource>
			<resource>
				<directory>src/main/resources</directory>
			</resource>
		</resources>
	</build>

</project>

启动类如下,因为需要部署到带域名的服务器Tomcat上,所以继承了SpringBootServletInitializer 并重写configure


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;


@SpringBootApplication
public class WeChatAuthApplication extends SpringBootServletInitializer {

	public static void main(String[] args) {
		SpringApplication.run(WeChatAuthApplication.class, args);
	}
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(WeChatAuthApplication.class);
    }
}

项目配置,主要是Log4j和项目名(因为需要部署到外部服务器的Tomcat上)

server.servlet.context-path=/wx
## LOG4J配置
log4j.rootCategory=DEBUG,stdout
## 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
logging.level.com.guide.springboot.server.mapper=debug

请求工具类,返回的是JSONObject,使用的是fastjson的jar包


import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
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 org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;


/**
 * 微信处理工具类
 * @author yinyunqi
 *
 */
@Service
public class WeChatUtil {
	
	private static final Logger log = LoggerFactory.getLogger(WeChatUtil.class);
	
	public static JSONObject weChatTest(String url) {
		CloseableHttpClient httpCilent = HttpClients.createDefault();
		HttpGet httpGet = new HttpGet(url);
		String result = "";
		JSONObject jsonObject = new JSONObject();
		try {
			HttpResponse httpResponse = httpCilent.execute(httpGet);
			if(httpResponse.getStatusLine().getStatusCode() == 200){
				result = EntityUtils.toString(httpResponse.getEntity());//获得返回的结果
				log.info(result);
				jsonObject = JSONObject.parseObject(result);
            }
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return jsonObject;
	}
	
}

页面

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Insert title here</title>
</head>
<body>
<a href="/wx/weChat/auth">点击获取权限</a>
</body>
</html>

请求处理类,代码中大部分都已注释

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
/**
 * 处理微信请求
 * @author yinyunqi
 *
 */
@Controller
public class WeChatController {
	private static final Logger log = LoggerFactory.getLogger(WeChatController.class);

	// 测试号平台 https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
	// 公众号的唯一标识【必需】
	public static final String APPID = "wx3cc7cac0b41e9111";
	// 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理【必需】
	public static final String REDIRECT_URI = "https://damionew.top/wx/weChat/callBack";
	// 返回类型,请填写code【必需】
	public static final String RESPONSE_TYPE = "code";
	// 应用授权作用域【必需】
	// snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid)
	// snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 )
	public static final String SCOPE = "snsapi_userinfo";
	// 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节【非必需】
	public static final String STATE = "123";
	// 无论直接打开还是做页面302重定向时候,必须带此参数【必需】
	public static final String wechat_redirect = "";
	public static final String APPSECRET = "b51067db03de9fa9d785e99db70b937e"; 
	
	/**
	 * 初始页面
	 * @return
	 */
	@RequestMapping("/weChat")
	public String weChatTest() {
		log.info("weChat");
		return "weChat";
	}
	
	/**
	 * 点击页面超链请求此处
	 * @param req
	 * @param res
	 */
	@ResponseBody
	@RequestMapping("/weChat/auth")
	public void weChatAuth(HttpServletRequest req,HttpServletResponse res) {
		String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+APPID
				+ "&redirect_uri="+REDIRECT_URI
				+ "&response_type="+RESPONSE_TYPE
				+ "&scope="+SCOPE
				+ "&state="+STATE
				+ "#wechat_redirect";
		log.info("url"+url);
		try {
			res.sendRedirect(url);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 上方 REDIRECT_URI 变量中带有的回调请求,即用户点击确定授权后所做的操作
	 * @param req
	 * @param res
	 */
	@ResponseBody
	@RequestMapping("weChat/callBack")
	public void weChatCallBack(HttpServletRequest req,HttpServletResponse res){
		String code = req.getParameter("code");
		log.info("code为:"+code);
		String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+APPID
				+ "&secret="+APPSECRET
				+ "&code="+code
				+ "&grant_type=authorization_code";
		JSONObject jsonObject = WeChatUtil.weChatTest(url);
		String openId = jsonObject.getString("openid");
		String access_token = jsonObject.getString("access_token");
		log.info("openid为"+openId);
		// 拉取用户信息
		String url2 = "https://api.weixin.qq.com/sns/userinfo?access_token="+access_token
				+ "&openid="+openId
				+ "&lang=zh_CN";
		JSONObject userInfo = WeChatUtil.weChatTest(url2);
		log.info("唯一标识为:" + userInfo.getString("openid"));
		log.info("昵称为:" + userInfo.getString("nickname"));
		log.info("性别为:" + userInfo.getString("sex"));
		log.info("省为:" + userInfo.getString("province"));
		log.info("市为:" + userInfo.getString("city"));
		log.info("头像地址为:" + userInfo.getString("headimgurl"));
	}
}

返回结果大致如下

这些都是通过服务器查看的打印日志信息,但最后发现,只能通过这种方式获取到openid,但可能并不符合客户预期

比如:绑定手机号码、微信号

但这也是微信为安全考虑,否则用户随便访问几个公众号,微信号手机号全暴露了,用户就可能会陷入无休止的被骚扰中

另外项目地址 GItHub

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值