1. 程式人生 > >java 微信授權登入

java 微信授權登入

可以自行查詢文件-

微信開放平臺

https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=b76e865cfb65ebc5f7fda8da68755abe4427731a&lang=zh_CN

微信pc端二維碼登入(電腦只能是掃碼登入)

第一步:請求CODE(注意-微信文件規定回撥地址必須外網可以訪問)

/**
* pc二維碼微信授權
* @param request
* @param response
*/
@RequestMapping(value = "/wx_login1", method = RequestMethod.GET)
public void wxU_login1(HttpServletRequest request, HttpServletResponse response){

try {
String state = StringUtilsEx.RandomString(32);
request.getSession().setAttribute("wechat_login", state);
redisService.set("wechat_login", state, 300);
String scope  = "snsapi_login";//靜默授權  只能獲取access_token和openID,流程走完即終止,snsapi_userinfo可以獲取更詳細的使用者資料,比如頭像、暱稱、性別等

//String url = URLEncoder.encode(CALLBACKDOMAIN+"wechat_charge.do?cardnum=" + cardnum + "&userid=" + userid + "&agentid=" + agentid, "utf-8");
String url = URLEncoder.encode("http://api.hestia.me/m/validate/M5V5VI9D0EE/"+"v1/user/callback.do" , "utf-8");//CALLBACK_DOMAIN為授權回撥頁面域名

//獲取code


String code_url = "https://open.weixin.qq.com/connect/qrconnect?appid=" +APPIDPC 
+ "&redirect_uri=" + url + "&response_type=code&scope=" + scope + "&state="+state+"#wechat_redirect";

response.sendRedirect(code_url);//可以獲取code 資訊並且轉發到redirect_uri的地址裡

} catch (Exception e) {
e.printStackTrace();
}
}

第二步:通過code獲取access_token

/**
* pc二維碼微信授權回撥
* @param request
* @param response
*/
@RequestMapping(value = "/callback", method = RequestMethod.GET)
public void callback(HttpServletRequest request, HttpServletResponse response){
String code_url=null;
try {
String back_state = request.getParameter("state");
String state =redisService.get("wechat_login")
redisService.del("wechat_login");
String code = request.getParameter("code");//授權時候,微信會吧引數傳到這裡
if(!StringUtils.equalsIgnoreCase(back_state, state)){
throw new ServiceException("請求無效!");
}
String access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token"+"?appid=" + APPIDPC+ "&secret=" + AppSecretPC + "&code=" + code + "&grant_type=authorization_code";
String access_token_str;
/*RestTemplate restTemplate=new RestTemplate();
String access_token_str1= restTemplate.getForObject(access_token_url, String.class);
logger.info(access_token_str1);
*/
access_token_str = httpAPIService.doGet(access_token_url);
logger.info("----------->> access_token_str:"+access_token_str);
if(StringUtils.isBlank(access_token_str)){throw new ServiceException("微信授權訪問通訊異常!");}

Map tokenmap = JSONUtilsEx.deserialize(access_token_str, Map.class);
if(tokenmap.get("errcode") != null){
throw new ServiceException("獲取token失敗:"+ObjectUtils.defaultIfNull(tokenmap.get("errmsg"), ""));
}
String openid = String.valueOf(tokenmap.get("openid"));
String token = String.valueOf(tokenmap.get("access_token"));
Map<String, String> info = new HashMap<String, String>();
info.put("openid", openid);
info.put("token", token);
String key = "wechat_login_user"+openid;
redisService.set(key, JSONUtilsEx.serialize(info), 300);
//

code_url = infourl.replaceAll("\\{openid\\}", openid); 
   code_url = "http://192.168.1.79:8090/mywx.shtml?openid="+openid; //轉發地址-mywx.shtml頁面是一個空頁面只是為了接受引數轉發介面
   response.sendRedirect(code_url);
  
} catch (Exception e) {
e.printStackTrace();
}

}

第三步-頁面mywx.shtml

頁面獲取上面方法傳過來的引數openid頁面ajax請求介面名為toLogin

/**
* 回撥之後獲取oppenid返回到的頁面
* @param request
* @param response
*/
@RequestMapping(value = "/toLogin", method = RequestMethod.GET)
public ResponseEntity<JsonResult> toLogin(HttpServletRequest request, HttpServletResponse response, ModelMap model){
JsonResult r = null;
//
try {
String openidS=request.getParameter("openid");
           if(openidS==null){
           throw new ServiceException("openid錯誤");
}
String key="wechat_login_user"+openidS;
String info =redisService.get(key);
JSONObject jsonObj = new JSONObject(info);
String openid=String.valueOf(jsonObj.get("openid"));
String token=String.valueOf(jsonObj.get("token"));
Map<String, String> info1 = new HashMap<String, String>();
info1.put("openid", openid);
info1.put("token", token);
   r= new JsonResult("0","ok", info1);
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.ok(r);

}

}

頁面獲取到openid和token在使用ajax請求傳送給登入介面

/**
* 登入驗證
* @param user
* @return
*/
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<JsonResult> login (@RequestBody(required=false) Map<String, String> user, HttpServletRequest request){
JsonResult r = null;
User v_user = null;
try {
//請求驗證
String ver_str = VerifyUtilsEx.verifyData(user, new String[] {"account", "pwd","appid","utype"});

if(StringUtils.isNotBlank(ver_str)){
throw new ServiceException(ver_str);
}
String ip = CommonUtilsEx.getIpAddr(request);
//校驗是否三方賬號登入
String utype = user.containsKey("utype") ? user.get("utype") : "";
if(StringUtils.isBlank(utype) || !"U_WX".equals(utype)){
v_user = userService.login(user.get("account"), user.get("pwd"), user.get("appid"),utype, ip);
}else{

v_user = userService.authLogin(user.get("account"), user.get("pwd"), user.get("appid"), utype, ip);//根據自己業務 在這個裡面根據openid和token獲取使用者資訊
}
TokenModel token = tokenManager.createToken(String.valueOf(v_user.getId()));

r= new JsonResult("0", "", token);

} catch(ServiceException se){
r= new JsonResult("-1", se.getMessage());

} catch (Exception e) {
r= new JsonResult("-2", "系統錯誤");
logger.error(e.getMessage());
e.printStackTrace();
}
return ResponseEntity.ok(r);
}

用到的工具類

public class HttpUtilEx {
private static Logger logger = LoggerFactory.getLogger(HttpUtilEx.class);  


/** 
     * get請求 
     * @return 
     */  
    public static String doGet(String url) {  
        try {  
        CloseableHttpClient client = HttpClients.createDefault();  
            //傳送get請求  
            HttpGet request = new HttpGet(url);  
            CloseableHttpResponse response = client.execute(request);  
   
            /**請求傳送成功,並得到響應**/  
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
                /**讀取伺服器返回過來的json字串資料**/  
                String strResult = EntityUtils.toString(response.getEntity());  
                  
                return strResult;  
            }  
        }catch (IOException e) {  
            e.printStackTrace();  
        }  
          
        return null;  
    }  

}

public class JSONUtilsEx {

/**
* JSON字串反序列化成物件
* @param jsonStr
* @param clazz
* @return
* @throws ServiceException 
*/
public static <T> T deserialize(String jsonStr, Class<T> clazz) throws ServiceException {


if (StringUtils.isEmpty(jsonStr)) {
return null;
}


try {
return mapper.readValue(jsonStr.replace("\n", ""), clazz);
} catch (Exception e) {
throw new ServiceException("JSON反序列化結果異常:" + e.getMessage());
}
}

}

時間有點趕,有什麼問題可以給我留言!我會及時給你回覆!

後續會更新手機端的授權

微信公眾號的支付,前後端的整個流程,會寫的更詳細