微信公众号受权登陆

一、配置服务器信息

* 基本配置/ 填写服务器配置    按提示输入信息,这个环节须要注意的是token微信会在线验证,提早写好拦截器java

拦截器代码git

/***
 * 微信验签拦截器
 */
public class WxAuthenticationInterceptor implements HandlerInterceptor {
    /**
     * 控制验签系统开闭
     */
    private final Boolean isOpen; public WxAuthenticationInterceptor(Boolean isOpen) { this.isOpen = isOpen; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (isOpen){ // 只拦截method级别的处理器 if (!(handler instanceof HandlerMethod)) return true; // 只拦截token注解过的方法 HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); // 判断接口是否须要验签 WxSign signAnnotation = method.getAnnotation(WxSign.class); if (signAnnotation != null){ String url = RequestUtil.getParameters(request); if (StringUtils.isNotBlank(request.getParameter("signature"))) { String signature = request.getParameter("signature"); String timestamp = request.getParameter("timestamp"); String nonce = request.getParameter("nonce"); String echostr = request.getParameter("echostr"); //LOGGER.info("signature[{}], timestamp[{}], nonce[{}], echostr[{}]", signature, timestamp, nonce, echostr); if (SignUtil.checkSignature(signature, timestamp, nonce)) { System.err.println(url + "数据源为微信后台,将echostr[" + echostr + "]返回!");
              return true;
}else{ throw new InfoException("验签错误"); } }else{ throw new InfoException("验签失败"); } } } return true; } }

 

验证地址bootstrap

@WxSign
@GetMapping(value = {"","wxVerify"})
@ResponseBody
public String index(HttpServletRequest request){
String echostr = request.getParameter("echostr");
return echostr;
}

 

SignUtil.javaapi

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

public class SignUtil {

    private static String token = "jiangxinpai";//这里是自定义的token,需和你提交的token一致

    /**
     * 校验签名
     *
     * @param signature
     *            签名
     * @param timestamp
     *            时间戳
     * @param nonce
     *            随机数
     * @return 布尔值
     */
    public static boolean checkSignature(String signature, String timestamp, String nonce) {
        String checktext = null;
        if (null != signature) {
            // 对ToKen,timestamp,nonce 按字典排序
            String[] paramArr = new String[] { token, timestamp, nonce };
            Arrays.sort(paramArr);
            // 将排序后的结果拼成一个字符串
            String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);

            try {
                MessageDigest md = MessageDigest.getInstance("SHA-1");
                // 对接后的字符串进行sha1加密
                byte[] digest = md.digest(content.toString().getBytes());
                checktext = byteToStr(digest);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
        // 将加密后的字符串与signature进行对比
        return checktext != null ? checktext.equals(signature.toUpperCase()) : false;
    }

    /**
     * 将字节数组转化为16进制字符串
     *
     * @param byteArrays
     *            字符数组
     * @return 字符串
     */
    private static String byteToStr(byte[] byteArrays) {
        String str = "";
        for (int i = 0; i < byteArrays.length; i++) {
            str += byteToHexStr(byteArrays[i]);
        }
        return str;
    }

    /**
     * 将字节转化为十六进制字符串
     *
     * @param myByte
     *            字节
     * @return 字符串
     */
    private static String byteToHexStr(byte myByte) {
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        char[] tampArr = new char[2];
        tampArr[0] = Digit[(myByte >>> 4) & 0X0F];
        tampArr[1] = Digit[myByte & 0X0F];
        String str = new String(tampArr);
        return str;
    }

}

 

 

 

2.获取accessToken, OAuth过程

@GetMapping("/oauth")
    public String oauth(HttpServletRequest request, HttpServletResponse response, String code, String state){
        //code说明 : code做为换取access_token的票据,每次用户受权带上的code将不同,code只能使用一次,5分钟未被使用自动过时。
        /*错误返回码说明以下:
        返回码    说明
        10003    redirect_uri域名与后台配置不一致
        10004    此公众号被封禁
        10005    此公众号并无这些scope的权限
        10006    必须关注此测试号
        10009    操做太频繁了,请稍后重试
        10010    scope不能为空
        10011    redirect_uri不能为空
        10012    appid不能为空
        10013    state不能为空
        10015    公众号未受权第三方平台,请检查受权状态
        10016    不支持微信开放平台的Appid,请使用公众号Appid*/
        WxAccessToken wxAccessToken = WxApiUtil.getAccessToken(code);
        if(wxAccessToken != null){
            String userIp = RequestUtil.getIp(request);

            WxUserInfo userInfo = WxApiUtil.getUserInfo(wxAccessToken.getAccess_token(), wxAccessToken.getOpenid());
            if(userInfo != null){
                //预注册帐号
               try {
                   User user = userFacadeService.registerWithWx(wxAccessToken.getOpenid(), wxAccessToken.getAccess_token()
                           , userInfo.getNickname(), userInfo.getHeadimgurl(), userIp);
                   if(user != null) {
                       try {
                           response.sendRedirect(Constant.AppUrl  + "/pages/user/bootstrap/bind?userId=" + user.getUserId() + "");
                       } catch (IOException e) {
                           e.printStackTrace();
                       }
                   }
               }catch (Exception e){
                   try {
                       response.sendRedirect(Constant.AppUrl  + "/pages/user/bootstrap/login?pop=" + e.getMessage());
                   } catch (IOException ex) {
                       ex.printStackTrace();
                   }
               }

            }
        }
        try {
            response.sendRedirect(Constant.AppUrl  + "/pages/user/bootstrap/login?pop=" + "微信登陆受权失败");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "ERROR";
    }

 

WxApiUtil.java数组

public class WxApiUtil {
    private final static String appId = "";
    private final static String appSecret = "";

    public static String getAccessToken(){
        /*grant_type    是    获取access_token填写client_credential
        appid    是    第三方用户惟一凭证
        secret    是    第三方用户惟一凭证密钥,即appsecret*/
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
        String response = HttpUtil.get(url, null);
        return response;
    }

    public static void main(String[] args) {
        String accessToken = WxApiUtil.getAccessToken();
        System.out.println(accessToken);
    }

    public static WxAccessToken getAccessToken(String code) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret + "&code=" + code+ "&grant_type=authorization_code";
        String response = HttpUtil.get(url, null);
        /*{
            "access_token":"ACCESS_TOKEN",
                "expires_in":7200,
                "refresh_token":"REFRESH_TOKEN",
                "openid":"OPENID",
                "scope":"SCOPE"
        }*/
        if(!response.contains("errcode")){
            WxAccessToken wxAccessToken = JsonUtil.getModel(response, WxAccessToken.class);
            return wxAccessToken;
        }else {
            System.err.println("getAccessToken:" + response);
        }
        return null;
    }


    public static WxUserInfo getUserInfo(String accessToken, String openId){
        /*{
            "openid":" OPENID",
                " nickname": NICKNAME,
                "sex":"1",
                "province":"PROVINCE"
            "city":"CITY",
                "country":"COUNTRY",
                "headimgurl":       "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
                "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
            "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
        }*/
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+ accessToken + "&openid=" + openId + "&lang=zh_CN";
        String response = HttpUtil.get(url, null);
        if(!response.contains("errcode")){
            WxUserInfo wxUserInfo = JsonUtil.getModel(response, WxUserInfo.class);
            return wxUserInfo;
        }else{
            System.err.println("getUserInfo:" + response);
        }
        return null;
    }
}

 

 

到此就完成任务啦~  微信用户打开H5后请求获取用户信息,无感预注册帐户,等到受权结束后再让用户绑定手机号推广码等等信息,若是报错了就重定向弹窗告知用户。服务器

相关文章
相关标签/搜索