首页 小程序 微信公众号授权登录,获取用户信息openid(亲测有效)

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

需求:客户登录微信公众号进行账号注册,绑定微信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 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;    }    @Override    public 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 wxde2a7fa4a2f8cf81";        //String appId = "wx7bb68b0432c87b0e";        log.debug("appId:" + appId);        // 测试号信息里的appsecret        String appsecret = "aabd5ba75129c3986b544e1a925eacd0";        //String appsecret = "370bd77c35322176f3410809d7a56c3c";        log.debug("secret:" + appsecret);        // 根据传入的code,拼接出访问微信定义好的接口的URL        String 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.获取用户accessToken失败。");            return null;        }        return token;    }        public static WechatUser getUserInfo(String accessToken, String openId) {        // 根据传入的accessToken以及openId拼接出访问微信定义的端口并获取用户信息的URL        String 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.获取用户信息失败。");            return null;        }        return user;    }        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;public accessToken:" + this.getAccessToken() + ",openId:" + this.getOpenId();    }}

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

import javax.net.ssl.X509TrustManager;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;public /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_token                token = WechatUtil.getUserAccessToken(code);                //log.debug("weixin login token:" + token.toString());                // 通过token获取accessToken                String accessToken = token.getAccessToken();                // 通过token获取openId                openId = 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.;}

界面优先加载此方法。

7、请求校验接口

import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Arrays;public weixinCourse";        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;    }        private static String byteToStr(byte[] byteArray) {        String strDigest = "";        for (int i = 0; i < byteArray.length; i++) {            strDigest += byteToHexStr(byteArray[i]);        }        return strDigest;    }        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;public weixinCourse";        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;    }        private static String byteToStr(byte[] byteArray) {        String strDigest = "";        for (int i = 0; i < byteArray.length; i++) {            strDigest += byteToHexStr(byteArray[i]);        }        return strDigest;    }        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 > 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

特别声明:本站部分内容收集于互联网是出于更直观传递信息的目的。该内容版权归原作者所有,并不代表本站赞同其观点和对其真实性负责。如该内容涉及任何第三方合法权利,请及时与824310991@qq.com联系,我们会及时反馈并处理完毕。