需求:客户登录微信公众号进行账号注册,绑定微信openid,下次根据openid验证自动登录。

详细代码:https://download.csdn.net/download/yaya_jn/74920268

一、微信公众平台配置。

1、配置业务域名

2、查看公众号appid

3、开通获取用户基本信息的权限

二、接口开发对接

1、微信用户实体类,用来接收昵称 openid等用户信息

import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;/*** 微信用户实体类*/
public class WechatUser implements Serializable {private static final long serialVersionUID = -4684067645282292327L;// openId,标识该公众号下面的该用户的唯一Id@JsonProperty("openid")private String openId;// 用户昵称@JsonProperty("nickname")private String nickName;// 性别@JsonProperty("sex")private int sex;// 省份@JsonProperty("province")private String province;// 城市@JsonProperty("city")private String city;// 区@JsonProperty("country")private String country;// 头像图片地址@JsonProperty("headimgurl")private String headimgurl;// 语言@JsonProperty("language")private String language;// 用户权限,这里没什么作用@JsonProperty("privilege")private String[] privilege;public String getOpenId() {return openId;}public void setOpenId(String openId) {this.openId = openId;}public String getNickName() {return nickName;}public void setNickName(String nickName) {this.nickName = nickName;}public int getSex() {return sex;}public void setSex(int sex) {this.sex = sex;}public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public String getCountry() {return country;}public void setCountry(String country) {this.country = country;}public String getHeadimgurl() {return headimgurl;}public void setHeadimgurl(String headimgurl) {this.headimgurl = headimgurl;}public String getLanguage() {return language;}public void setLanguage(String language) {this.language = language;}public String[] getPrivilege() {return privilege;}public void setPrivilege(String[] privilege) {this.privilege = privilege;}@Overridepublic String toString() {return "openId:" + this.getOpenId() + ",nikename:" + this.getNickName();}
}

2、微信工具类

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;/*** 微信工具类*/
public class WechatUtil {//private static Logger log = LoggerFactory.getLogger(WechatUtil.class);/*** 获取UserAccessToken实体类* @param code* @return* @throws IOException*/public static UserAccessToken getUserAccessToken(String code) throws IOException {// 测试号信息里的appIdString appId = "wxde2a7fa4a2f8cf81";//String appId = "wx7bb68b0432c87b0e";log.debug("appId:" + appId);// 测试号信息里的appsecretString appsecret = "aabd5ba75129c3986b544e1a925eacd0";//String appsecret = "370bd77c35322176f3410809d7a56c3c";log.debug("secret:" + appsecret);// 根据传入的code,拼接出访问微信定义好的接口的URLString url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appsecret+ "&code=" + code + "&grant_type=authorization_code";System.out.println("getUserAccessToken ---------------------------------------------------------------------------"+url);// 向相应URL发送请求获取token json字符串String tokenStr = httpsRequest(url, "GET", null);log.debug("userAccessToken:" + tokenStr);UserAccessToken token = new UserAccessToken();ObjectMapper objectMapper = new ObjectMapper();try {// 将json字符串转换成相应对象token = objectMapper.readValue(tokenStr, UserAccessToken.class);} catch (JsonParseException e) {log.error("获取用户accessToken失败: " + e.getMessage());e.printStackTrace();} catch (JsonMappingException e) {log.error("获取用户accessToken失败: " + e.getMessage());e.printStackTrace();} catch (IOException e) {log.error("获取用户accessToken失败: " + e.getMessage());e.printStackTrace();}if (token == null) {log.error("获取用户accessToken失败。");return null;}return token;}/*** 获取WechatUser实体类* @param accessToken* @param openId* @return*/public static WechatUser getUserInfo(String accessToken, String openId) {// 根据传入的accessToken以及openId拼接出访问微信定义的端口并获取用户信息的URLString url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId+ "&lang=zh_CN";// 访问该URL获取用户信息json 字符串String userStr = httpsRequest(url, "GET", null);//log.debug("user info :" + userStr);WechatUser user = new WechatUser();ObjectMapper objectMapper = new ObjectMapper();try {// 将json字符串转换成相应对象user = objectMapper.readValue(userStr, WechatUser.class);} catch (JsonParseException e) {//log.error("获取用户信息失败: " + e.getMessage());e.printStackTrace();} catch (JsonMappingException e) {//log.error("获取用户信息失败: " + e.getMessage());e.printStackTrace();} catch (IOException e) {//log.error("获取用户信息失败: " + e.getMessage());e.printStackTrace();}if (user == null) {//log.error("获取用户信息失败。");return null;}return user;}/*** 发起https请求并获取结果* @param requestUrl*            请求地址* @param requestMethod*            请求方式(GET、POST)* @param outputStr*            提交的数据* @return json字符串*/public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {StringBuffer buffer = new StringBuffer();try {// 创建SSLContext对象,并使用我们指定的信任管理器初始化TrustManager[] tm = { new MyX509TrustManager() };SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");sslContext.init(null, tm, new java.security.SecureRandom());// 从上述SSLContext对象中得到SSLSocketFactory对象SSLSocketFactory ssf = sslContext.getSocketFactory();URL url = new URL(requestUrl);HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();httpUrlConn.setSSLSocketFactory(ssf);httpUrlConn.setDoOutput(true);httpUrlConn.setDoInput(true);httpUrlConn.setUseCaches(false);// 设置请求方式(GET/POST)httpUrlConn.setRequestMethod(requestMethod);if ("GET".equalsIgnoreCase(requestMethod))httpUrlConn.connect();// 当有数据需要提交时if (null != outputStr) {OutputStream outputStream = httpUrlConn.getOutputStream();// 注意编码格式,防止中文乱码outputStream.write(outputStr.getBytes("UTF-8"));outputStream.close();}// 将返回的输入流转换成字符串InputStream inputStream = httpUrlConn.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String str = null;while ((str = bufferedReader.readLine()) != null) {buffer.append(str);}bufferedReader.close();inputStreamReader.close();// 释放资源inputStream.close();inputStream = null;httpUrlConn.disconnect();//log.debug("https buffer:" + buffer.toString());} catch (ConnectException ce) {//log.error("Weixin server connection timed out.");} catch (Exception e) {//log.error("https request error:{}", e);}return buffer.toString();}
}

3、用户AccessToken实体类,用来接收accesstoken以及openid等信息

import com.fasterxml.jackson.annotation.JsonProperty;/*** 用户授权token**/
public class UserAccessToken {// 获取到的凭证@JsonProperty("access_token")private String accessToken;// 凭证有效时间,单位:秒@JsonProperty("expires_in")private String expiresIn;// 表示更新令牌,用来获取下一次的访问令牌,这里没太大用处@JsonProperty("refresh_token")private String refreshToken;// 该用户在此公众号下的身份标识,对于此微信号具有唯一性@JsonProperty("openid")private String openId;// 表示权限范围,这里可省略@JsonProperty("scope")private String scope;public String getAccessToken() {return accessToken;}public void setAccessToken(String accessToken) {this.accessToken = accessToken;}public String getExpiresIn() {return expiresIn;}public void setExpiresIn(String expiresIn) {this.expiresIn = expiresIn;}public String getRefreshToken() {return refreshToken;}public void setRefreshToken(String refreshToken) {this.refreshToken = refreshToken;}public String getOpenId() {return openId;}public void setOpenId(String openId) {this.openId = openId;}public String getScope() {return scope;}public void setScope(String scope) {this.scope = scope;}@Overridepublic String toString() {return "accessToken:" + this.getAccessToken() + ",openId:" + this.getOpenId();}}

4、证书信任管理器(用于https请求)

import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;/*** 证书信任管理器(用于https请求)**/
public class MyX509TrustManager implements X509TrustManager {public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}public X509Certificate[] getAcceptedIssuers() {return null;}
}

5、微信回调接口

import com.ruoyi.project.api.controller.weixin.UserAccessToken;
import com.ruoyi.project.api.controller.weixin.WechatUser;
import com.ruoyi.project.api.controller.weixin.WechatUtil;
import com.ruoyi.project.bis.member.domain.Member;
import com.ruoyi.project.bis.member.service.IMemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 获取关注公众号之后的微信用户信息的接口,如果在微信浏览器里访问* https://open.weixin.qq.com/connect/oauth2/authorize?appid=您的appId&redirect_uri=http://o2o.yitiaojieinfo.com/o2o/wechatlogin/logincheck&role_type=1&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect* 则这里将会获取到code,之后再可以通过code获取到access_token 进而获取到用户信息*/
@Controller
@RequestMapping("/api/wechatlogin")
public class WechatLoginController {@Autowiredprivate IMemberService memberService;@Autowiredprivate MemberCenterController memberCenterController;//private static Logger log = LoggerFactory.getLogger(WechatLoginController.class);@GetMapping(value = "/logincheck")public String doGet(HttpServletRequest request, HttpServletResponse response,ModelMap modelMap,String userCode) {//log.debug("weixin login get...");modelMap.put("userCode",userCode);System.out.println("weixin login get... --------");// 获取微信公众号传输过来的code,通过code可获取access_token,进而获取用户信息String code = request.getParameter("code");System.out.println("weixin login get... code--------------"+code);// 这个state可以用来传我们自定义的信息,方便程序调用,这里也可以不用// String roleType = request.getParameter("state");//log.debug("weixin login code:" + code);WechatUser user = null;String openId = null;if (null != code) {UserAccessToken token;try {// 通过code获取access_tokentoken = WechatUtil.getUserAccessToken(code);//log.debug("weixin login token:" + token.toString());// 通过token获取accessTokenString accessToken = token.getAccessToken();// 通过token获取openIdopenId = token.getOpenId();// 通过access_token和openId获取用户昵称等信息user = WechatUtil.getUserInfo(accessToken, openId);//log.debug("weixin login user:" + user.toString());//request.getSession().setAttribute("openId", openId);modelMap.put("openId",openId);System.out.println("openIdkais---------------"+openId);} catch (IOException e) {//log.error("error in getUserAccessToken or getUserInfo or findByOpenId: " + e.toString());e.printStackTrace();}}else{//memberCenterController.center(openId,modelMap);}// ======todo begin======// 前面咱们获取到openId后,可以通过它去数据库判断该微信帐号是否在我们网站里有对应的帐号了,// 没有的话这里可以自动创建上,直接实现微信与咱们网站的无缝对接。// ======todo end======if (user != null) {// 获取到微信验证的信息后返回到指定的路由(需要自己设定)//Member member =  memberService.selectMemberByOpenId(openId);if(member!=null){//return memberCenterController.center(openId,modelMap);}else{return "h5/register";}} else {return "h5/userCenter";}}

}

6、前端界面编辑回调接口

function weixinApply() {//验证是否需要登录window.location.href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=*********&redirect_uri=http://域名/api/wechatlogin/logincheck&role_type=1&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect";
}

界面优先加载此方法。

7、请求校验接口

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;/*** 描述:请求校验工具类.* @author zrxJuly* @createDate 2017-12-9* @since 1.0**/
public class SignUtil {// 与开发模式接口配置信息中的Token保持一致.private static String token = "weixinCourse";/*** 校验签名* @param signature 微信加密签名.* @param timestamp 时间戳.* @param nonce 随机数.* @return*/public static boolean checkSignature(String signature, String timestamp, String nonce) {// 对token、timestamp、和nonce按字典排序.String[] paramArr = new String[] {token, timestamp, nonce};Arrays.sort(paramArr);// 将排序后的结果拼接成一个字符串.String content  = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);String ciphertext = null;try {MessageDigest md = MessageDigest.getInstance("SHA-1");// 对拼接后的字符串进行sha1加密.byte[] digest = md.digest(content.toString().getBytes());ciphertext = byteToStr(digest);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}// 将sha1加密后的字符串与signature进行对比.return ciphertext != null ? ciphertext.equals(signature.toUpperCase()) : false;}/*** 将字节数组转换为十六进制字符串.* @param byteArray* @return*/private static String byteToStr(byte[] byteArray) {String strDigest = "";for (int i = 0; i < byteArray.length; i++) {strDigest += byteToHexStr(byteArray[i]);}return strDigest;}/*** 将字节转换为十六进制字符串.* @param mByte* @return*/private static String byteToHexStr(byte mByte) {char[] Digit = { '0', '1' , '2', '3', '4' , '5', '6', '7' , '8', '9', 'A' , 'B', 'C', 'D' , 'E', 'F'};char[] tempArr = new char[2];tempArr[0] = Digit[(mByte >>> 4) & 0X0F];tempArr[1] = Digit[mByte & 0X0F];String s = new String(tempArr);return s;}}

三、电脑线下测试方法。

1、申请公众平台测试账号

2、注册小米球 登录小米球Ngrok后台系统,可以将本机配置域名,然后和微信进行通信。

根据windows版本下载运行,解压版本的不需要安装(下载密码:小米球拼音)

注册账号,会获得小米球Token,此处我花了5毛钱实名认证了一下,因为后续连接的时候会连接不上。


按照教程更改token启动小米球获取域名

3、微信测试账号配置及认证

appID:开发者ID,是公众号开发识别码,配合开发者密码可以调用微信公众号接口,如获取微信昵称等
appsecret:开发者密码,是检验公众号开发者身份的密码,具有极高的安全性。切记不要把密码交给第三方开发者或者编写到代码里

【接口配置信息】
URL: 是开发者用来接收微信消息和事件的接口URL,要用域名不能用ip
Token:由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)

4、当你填完URL和Token点击提交后,微信会访问你填写的URL,所以要在后台写一个servlet来处理这个请求(上代码)

(1)、工具类 请求校验,token值和微信配置一致

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;/*** 描述:请求校验工具类.* @author zrxJuly* @createDate 2017-12-9* @since 1.0**/
public class SignUtil {// 与开发模式接口配置信息中的Token保持一致.private static String token = "weixinCourse";/*** 校验签名* @param signature 微信加密签名.* @param timestamp 时间戳.* @param nonce 随机数.* @return*/public static boolean checkSignature(String signature, String timestamp, String nonce) {// 对token、timestamp、和nonce按字典排序.String[] paramArr = new String[] {token, timestamp, nonce};Arrays.sort(paramArr);// 将排序后的结果拼接成一个字符串.String content  = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);String ciphertext = null;try {MessageDigest md = MessageDigest.getInstance("SHA-1");// 对拼接后的字符串进行sha1加密.byte[] digest = md.digest(content.toString().getBytes());ciphertext = byteToStr(digest);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}// 将sha1加密后的字符串与signature进行对比.return ciphertext != null ? ciphertext.equals(signature.toUpperCase()) : false;}/*** 将字节数组转换为十六进制字符串.* @param byteArray* @return*/private static String byteToStr(byte[] byteArray) {String strDigest = "";for (int i = 0; i < byteArray.length; i++) {strDigest += byteToHexStr(byteArray[i]);}return strDigest;}/*** 将字节转换为十六进制字符串.* @param mByte* @return*/private static String byteToHexStr(byte mByte) {char[] Digit = { '0', '1' , '2', '3', '4' , '5', '6', '7' , '8', '9', 'A' , 'B', 'C', 'D' , 'E', 'F'};char[] tempArr = new char[2];tempArr[0] = Digit[(mByte >>> 4) & 0X0F];tempArr[1] = Digit[mByte & 0X0F];String s = new String(tempArr);return s;}}

(2)处理请求Controller

@Controller
@RequestMapping("wechat")
public class WeiXinController {
    @RequestMapping(method = { RequestMethod.GET })
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");
        // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
        PrintWriter out = null;
        try {
            out = response.getWriter();
            if (SignUtil.checkSignature(signature, timestamp, nonce)) {
                log.debug("weixin get success....");
                out.print(echostr);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null)
                out.close();
        }
    }
}

请求的处理程序写完后启动项目,再提交你填写的URL和Token,接口配置信息就Ok啦

5、配置微信获取用户信息域名(直接配置小米球的域名就ok)

6、配置完成然后和第二步的代码层结合,下载在线调试工具访问就可以调试了。

只能帮到这了,如果还不会此处是代码,自己下载看看。https://download.csdn.net/download/yaya_jn/74920268

微信公众号授权登录,获取用户信息openid(亲测有效)相关推荐

  1. Spring boot 项目(十三)——实现微信公众号授权登录获取用户信息

    引言 微信公众号开发中,必不可少的一环:公众号授权登录.获取微信用户信息 前期准备 内网渗透=>生成本地指定端口映射的外网域名 链接:内网渗透工具natapp使用详解 域名生成之后修改yml文件 ...

  2. 基于Spring Boo微信公众号授权登录获取用户信息(附带完整源码)

    简介 微信公众号开发中,必不少可少的一环:公众号授权登录.获取微信用户信息. 本地完整运行环境准备 内网渗透=>生成本地指定端口映射的外网域名 传送门:内网渗透工具Natapp使用详解 域名生成 ...

  3. java实现微信公众号授权登录获取用户信息(一)

    参考文章:https://blog.csdn.net/Santiago_M/article/details/79109154 : https://www.cnblogs.com/jilu/p/6123 ...

  4. Spring Boot + 微信公众号授权登录获取用户信息

    通过微信公众平台的官方文档,总结出网页授权流程分为: 1.引导用户进入授权页面同意授权,获取code 2.通过code换取网页授权access_token(与基础支持中的access_token不同) ...

  5. 微信公众号授权(获取用户信息)

    需要的工具: 微信公众号(可以申请,但做开发的,可以申请测试号,申请详细不多说了) 服务器(可以自行购买,我使用的是新浪的sae.) 编辑器(随意,不做推荐) 微信公众号开发文档(地址) !!!!!完 ...

  6. 微信小程序授权登录获取用户信息详解

    今天来说一下微信小程序的授权登录获取用户信息,首先我们看微信提供的小程序开发文档: https://blog.csdn.net/qq_41971087/article/details/82466647 ...

  7. 微信公众号接入和获取用户信息

    主要原理: 1.从微信公众号发来的get请求为验证服务器安全性的 2.从微信公众号发来的post请求为接受和回复用户信息的 3.先根据是否有code来进行判断,如果有code的话,根据code换取op ...

  8. 微信公众号开发之获取用户信息

    微信获取用户信息的方式有两种,静默授权(无需用户同意)和非静默授权(需要用户" 手动点击 "拉取授权,可以用户无需关注公众号即可获取用户信息) 整体的代码请查看最后,前边为原理介绍 ...

  9. 微信小程序授权登录获取用户信息并保存至缓存用于下次登录

    1.获取用户信息 wx.getUserProfile(Object object) 获取用户信息.页面产生点击事件(例如 button 上 bindtap 的回调中)后才可调用,每次请求都会弹出授权窗 ...

  10. 微信小程序授权登录——获取用户信息

    小程序登录 小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系. 登录流程时序 效果展示: 功能实现: 新建一个login页面 login.js: wx. ...

最新文章

  1. ML之DT:基于简单回归问题训练决策树(DIY数据集+三种深度的二元DT性能比较)
  2. intel lock汇编指令保障有序性
  3. JSON的應用(Javascript Object Nonation)
  4. HMM和CRF 条件随机场详解
  5. java多线程nullpointerexception_温故而知新!越是基础越容易被忽略,java最全基础知识,附赠资料...
  6. python 英语翻译 excel_翻译篇Day2-用python读写Excel–数据图表篇
  7. mysql decimal 比较大小_10 分钟掌握 MySQL 的索引查询优化技巧
  8. ibatis.net:尽可能的使用匿名类型替换 Hashtable
  9. python刻度增加1个数_Matplotlib添加一个特定的勾号,表示轴的最大多个刻度单次观察...
  10. DuiLib教程--认识她
  11. i2c时序图(AT24C08)
  12. 黑客逆向破解基础-1:壳、加壳和脱壳分别是什么?加壳的解压原理介绍。
  13. 这一份Spring源码解析PDF,阿里架构师直言:全网最深度解析!
  14. 小程序外包开发指南:如何开发一款游戏?
  15. BZOJ3689 异或之
  16. Windows DiskPart
  17. Android root检测方法小结
  18. 格式转换——bmp 2 yuv
  19. openGauss数据库源码解析系列文章——存储引擎源码解析(四)
  20. GoogleEarth二次开发平台指南(2) ---如何把三维模型和图片导入到谷歌地球中

热门文章

  1. 苹果手机便签App如何设置今天待办事宜?
  2. arduino(9):使用ESP8266,连接到RFID RC522 设备上,读取门禁卡上的设备信息
  3. python管理微信公众号_个人微信公众号搭建Python实现 -个人公众号搭建-永久素材管理(14.3.5)...
  4. linux的ping命令属于OSI七层模型的哪一层?
  5. 写shell,运行出错:syntax error near unexpected token `do
  6. 用PS更换照片背景色
  7. CSS3 outline轮廓线
  8. Spring Boot 零xml整合dubbo
  9. 小米、华为、苹果、OV教给我们的战略课
  10. 从上帝视角认识一下https