微信公衆號受權登陸

一、配置服務器信息

* 基本配置/ 填寫服務器配置    按提示輸入信息,這個環節須要注意的是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後請求獲取用戶信息,無感預註冊帳戶,等到受權結束後再讓用戶綁定手機號推廣碼等等信息,若是報錯了就重定向彈窗告知用戶。服務器

相關文章
相關標籤/搜索