操作流程
假设你已经有自己的域名,因为微信公众号和微信回调都需要域名
先看看官方给的文档
根据官方文档,主要流程如下:
(1)引导用户进入授权页面同意授权,获取code
(2)通过code换取网页授权access_token(与基础支持中的access_token不同)
(3)刷新access_token(如果有需要)
(3)通过网页授权access_token和openid获取用户基本信息
提示:以下是本篇文章正文内容,下面案例可供参考
编写微信授权方法和获取用户信息方法
二、使用步骤
获取微信二维码信息
代码如下(示例):
/**
* 公众号微信登录授权
*/
@RequestMapping("/wxLogin")
public void wxLogin(HttpServletResponse response) throws IOException {
//这个url的域名必须在公众号中进行注册验证,这个地址是成功后的回调地址
String backUrl = "http://7ca0c439f61c.ngrok.io/callback";//使用自己的域名
// 第一步:用户同意授权,获取code
//请求地址 snsapi_base snsapi_userinfo
String url = "https://open.weixin.qq.com/connect/oauth2/authorize" +
"?appid=" + HttpClientUtil.APPID +
"&redirect_uri=" + URLEncoder.encode(backUrl,"utf-8") +
"&response_type=code" +
"&scope=snsapi_userinfo" +
"&state=STATE#wechat_redirect";
logger.info("forward重定向地址{" + url + "}");
//必须重定向,否则不能成功
response.sendRedirect(url);
}
备注:在前端页面直接加载url 就可以出现二维码界面了。直接用的微信的页面,也可以根据自己的爱好进行设计页面
/**
* 公众号微信登录授权回调函数
*/
@RequestMapping("/callback")
public UserLoginRes callback(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
UserLoginRes userLoginRes = new UserLoginRes();
try{
WXUserInfoReq weixinUserInfo = new WXUserInfoReq();
/*start 获取微信用户基本信息*/
String code = req.getParameter("code");
//第二步:通过code换取网页授权access_token
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
+ "appid=" + HttpClientUtil.APPID
+ "&secret=" + HttpClientUtil.APPSECRET
+ "&code=" + code
+ "&grant_type=authorization_code";
System.out.println(url);
String result = HttpClientUtil.doGet(url);
JSONObject jsonObject = JSON.parseObject(result);
/*
{ "access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
*/
String openid = jsonObject.getString("openid");
String access_token = jsonObject.getString("access_token");
//第三步验证access_token是否失效;
String chickUrl = "https://api.weixin.qq.com/sns/auth?access_token="
+ access_token + "&openid=" + openid;
String resultInfo = HttpClientUtil.doGet(chickUrl);
JSONObject chickuserInfo = JSON.parseObject(resultInfo);
System.out.println(chickuserInfo.toString());
if (!"0".equals(chickuserInfo.getString("errcode"))) {
String refreshInfo1 = HttpClientUtil.doGet(chickUrl);
JSONObject refreshInfo = JSON.parseObject(refreshInfo1);
/*
{ "access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE" }
*/
access_token = refreshInfo.getString("access_token");
}
// 第四步:拉取用户信息
String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token
+ "&openid=" + openid
+ "&lang=zh_CN";
JSONObject userInfo = JSON.parseObject(HttpClientUtil.doGet(infoUrl));
/*
{ "openid":" OPENID",
"nickname": NICKNAME,
"sex":"1",
"province":"PROVINCE"
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
*/
System.out.println(userInfo.getString("openid") + ":" + userInfo.getString("nickname") +":" + userInfo.getString("sex"));
}catch (Exception e){
e.printStackTrace();
userLoginRes.setResult("NO");
userLoginRes.setRtnErrId("ERROR");
userLoginRes.setRtnErrMsg(e.getMessage());
}
return userLoginRes;
}
使用到的HttpClientUtil工具类
代码如下(示例):
public class HttpClientUtil {
//appid、secret为自己公众号平台的appid和secret
public static final String APPID="xxxxxxx";
public static final String APPSECRET ="xxxxxxx";
public static String doGet(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response = null;
HttpGet httpGet = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 创建http GET请求
httpGet = new HttpGet(uri);
httpGet.setHeader("Host", "api.weixin.qq.com");
httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
httpGet.setHeader("Accept", "text/html, application/xhtml+xml, */*");
httpGet.setHeader("Accept-Encoding", "gzip, deflate, br");
httpGet.setHeader("Connection", "keep-alive");
httpGet.setHeader("Accept-Language", "zh-CN");
httpGet.setHeader("Cache-Control", "no-cache");
// 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpGet.releaseConnection();
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doGet(String url) {
return doGet(url, null);
}
public static String doPost(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doPost(String url) {
return doPost(url, null);
}
public static String doPostJson(String url, String json) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doGetStr(String httpurl) {
HttpURLConnection connection = null;
InputStream is = null;
BufferedReader br = null;
String result = null;// 返回结果字符串
try {
// 创建远程url连接对象
URL url = new URL(httpurl);
// 通过远程url连接对象打开一个连接,强转成httpURLConnection类
connection = (HttpURLConnection) url.openConnection();
// 设置连接方式:get
connection.setRequestMethod("GET");
// 设置连接主机服务器的超时时间:15000毫秒
connection.setConnectTimeout(15000);
// 设置读取远程返回的数据时间:60000毫秒
connection.setReadTimeout(60000);
//设置请求头
connection.setRequestProperty("Host", "api.weixin.qq.com");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
connection.setRequestProperty("Accept", "text/html, application/xhtml+xml, */*");
connection.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
connection.setRequestProperty("Connection", "keep-alive");
connection.setRequestProperty("Accept-Language", "zh-CN");
connection.setRequestProperty("Cache-Control", "no-cache");
// 发送请求
connection.connect();
// 通过connection连接,获取输入流
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
// 封装输入流is,并指定字符集
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
// 存放数据
StringBuffer sbf = new StringBuffer();
String temp = null;
while ((temp = br.readLine()) != null) {
sbf.append(temp);
sbf.append("\r\n");
}
result = sbf.toString();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭资源
if (null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
connection.disconnect();// 关闭远程连接
}
return result;
}
}
最后根据实际业务处理用户登录
//3.根据uuid查询用户是否存在,如果存在直接登录。如果不存在则自动注册,在登录
UserInfoModel userInfoByWechat = iUserDao.getUserInfoByWechat(userInfoStr.get("unionid").toString());
if (userInfoByWechat != null) {
return ReturnMessage.success(0,"获取成功",userInfoByWechat);
}
//4.数据库添加用户信息
String username = userInfoStr.get("nickname").toString();
String unionid = userInfoStr.get("unionid").toString();
UserInfoBean userInfoBean = new UserInfoBean();
userInfoBean.setUuid(unionid);
userInfoBean.setUsername(username);
// 微信登录
userInfoBean.setStatus(2);
iUserDao.insertUser(userInfoBean);
//5.根据uuid查询新注册的用户信息
UserInfoModel userInfoModel= iUserDao.getUserInfoByWechat(unionid);
if (userInfoModel == null) {
return ReturnMessage.fail(400,"用户添加失败,请重新操作");
}