网页版本微信通讯协议分析

阅读更多

        没事分析了下网页版本微信的通训协议,并且用java实现了登录,发送和接收消息,以后可以用来集成到后台,作为一个业务通知系统,就是每次登录需要扫码比较费事。

登录步骤:

1.打开首页,分配一个随机用户id,

2.根据该id获取二维码图片。

3.微信客户端扫描该图片,在客户端确认登录。

4.浏览器不停的调用一个接口,如果返回登录成功,则调用登录接口

5.此时可以获取联系人列表,可以发送消息。然后不断调用同步接口。

6.如果同步接口有返回,则可以获取新消息,然后继续调用同步接口。

 

贴上源码,仅供参考:(需要下载apache httpclient以及json)

package wwx;

import java.util.LinkedList;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

public class WebWeixin {
	String url_getuuid="https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_={t}";
	
	String url_login2weima="https://login.weixin.qq.com/qrcode/{}?t=webwx";
	
	String url_check_login="https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid={}&tip=1&_={t}";
	
	String url_init = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r={t}";
	
	String url_contactlist = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?r={t}";
	
	String url_synccheck = "https://webpush.weixin.qq.com/cgi-bin/mmwebwx-bin/synccheck?callback=jQuery18309326978388708085_1377482079946&r={t}&sid={0}&uin={1}&deviceid={2}&synckey={3}&_={t}";
	
	String url_msglist = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid={}&r={t}";
	
	String url_sendMsg = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?sid={}&r={t}";
	public static void main(String[] args) throws Exception{
		new WebWeixin().init();
//		new Test().getCookies("http://www.baidu.com");
//		System.out.println(System.currentTimeMillis(););
	}
	
	class UInfo{
		 String wxuin;
		 String wxsid;
		 String webwxuvid; 
		 String deviceid;
		 
		 String syncKey;
		 JSONObject SyncKey;
		 
		 String SKey;
		 
		 JSONObject ujson;
		 String name;	//帐号
		 String nickName;//昵称
		 
		 boolean connect = false;
	}
	UInfo u = new UInfo();
	Object wait = new Object();
	
	LinkedList listeners = new LinkedList();
	public void addListener(WxMsgListener lis){
		this.listeners.add(lis);
	}
	//开始登录微信
	public void start(){
		//1.取得uuid
		String getUUIDUrl = url_getuuid.replace("{t}", ""+System.currentTimeMillis());
		 String res = Utils.getUrl(getUUIDUrl);
		 
		 String uuid = "";
		 Pattern pat = Pattern.compile("window.QRLogin.code = ([0-9]+); window.QRLogin.uuid = \"([0-9a-z]+)\";");  
		 Matcher mat = pat.matcher(res);  
		 if(mat.find()){
			 System.out.println(mat.group(1));
			 System.out.println(mat.group(2));
			 uuid = mat.group(2);
		 }
		 //2.取得登录二维码
		 String url_login = url_login2weima.replace("{}", uuid);
		 System.out.println("login_url=>"+url_login);
		 String img_path = Utils.dowmImg(url_login);
		 System.out.println("img_path=>"+img_path);
		 //3.轮询手机端是否已经扫描二维码并确认在Web端登录
		 String login_url = check_login(uuid);
		 Map cookies = Utils.getCookies(login_url);
		 System.out.println("cookies = "+cookies);
		 u.wxuin = cookies.get("wxuin");
		 u.wxsid = cookies.get("wxsid");
		 u.webwxuvid = cookies.get("webwxuvid");
		 u.deviceid = "e960817075982756";
		 
		 //4.调用初始化url
		 JSONObject post = new JSONObject();
		 JSONObject BaseRequest = new JSONObject();
		 post.put("BaseRequest", BaseRequest);
		 BaseRequest.put("Uin", u.wxuin);
		 BaseRequest.put("Sid", u.wxsid);
		 BaseRequest.put("Skey", "");
		 BaseRequest.put("DeviceID", u.deviceid);
		 String intUrl = url_init.replace("{t}", ""+System.currentTimeMillis());
		 res = Utils.postUrl(intUrl, post.toString());
		 JSONObject init =  JSONObject.parseObject(res);
		 JSONObject user  = init.getJSONObject("User");
		 System.out.println("欢迎您:"+user);
		 u.ujson = user;
		 u.name = user.getString("UserName");
		 u.nickName = user.getString("NickName");
		 JSONObject SyncKey = init.getJSONObject("SyncKey"); 
		 u.syncKey = getSyncKey(init);
		 u.SyncKey = SyncKey;
		 
		 u.SKey = init.getString("SKey");
		 u.connect = true;
		 
		 startSyncCheck();
		 
		 u.connect = false;
		//				 System.out.println(res);
				 
	}
	
	public void init() throws Exception{
		while(true){
			Thread t =  new Thread(){
				public void run(){
					try {
						WebWeixin.this.start();
					} catch (Exception e) {
						e.printStackTrace();
						u.connect = false;
					}
					synchronized (wait) {
						wait.notify();
					}
				}
			};
			t.start();
			Thread.sleep(300 * 1000);
			if(!u.connect){
				t.interrupt();
			}else{
				synchronized (wait) {
					wait.wait();
				}
			}
		}
	}
	
	//取得synckey
	public String getSyncKey(JSONObject json){
		JSONObject SyncKey = json.getJSONObject("SyncKey");
		 JSONArray Listarr = SyncKey.getJSONArray("List");
		 String synckey = "";
		 for(int i = 0;i 0){
//					System.out.println("有"+count+"条新消息");
					
					String msgurl = url_msglist.replace("{}", u.wxsid);
					msgurl = msgurl.replace("{t}", ""+t);
					
					JSONObject post = new JSONObject();
					JSONObject BaseRequest = new JSONObject();
					BaseRequest.put("Uin", u.wxuin);
					BaseRequest.put("Sid", u.wxsid);
					post.put("BaseRequest", BaseRequest);
					post.put("SyncKey", u.SyncKey);
					post.put("rr", System.currentTimeMillis());
					
					res = Utils.postUrl(msgurl, post.toString());
					
//					System.out.println(res);
					
					JSONObject rj =   JSONObject.parseObject(res);
					u.SKey = rj.getString("SKey");
					if(u.SKey.equals("")){
						
						break;
					}
					JSONObject SyncKey = rj.getJSONObject("SyncKey"); 
					u.syncKey = getSyncKey(rj);
					u.SyncKey = SyncKey;
					
					
					JSONArray AddMsgList = rj.getJSONArray("AddMsgList");
					for(int i = 0;i getCookies(String url){
//		try {
//			CloseableHttpClient httpclient = HttpClients.createDefault();
//			HttpGet httpget = new HttpGet(url);
//			CloseableHttpResponse response = httpclient.execute(httpget, context);
//			try {
//				System.out.println(response);
////				System.out.println(context.getCookieStore());
//				CookieStore cs = context.getCookieStore();
//				Map map = new HashMap();
//				for(Cookie c : cs.getCookies()){
//					map.put(c.getName(), c.getValue());
//				} 
//				return map;
//			} finally {
//			    response.close();
//			}
//		} catch (ClientProtocolException e) {
//			e.printStackTrace();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//		return null;
//	}
//	
//	//down img
//	public static String dowmImg(String url){
//		try {
//			CloseableHttpClient httpclient = HttpClients.createDefault();
//			HttpGet httpget = new HttpGet(url);
//			CloseableHttpResponse response = httpclient.execute(httpget, context);
//			try {
////				System.out.println(response);
//				byte [] bs = EntityUtils.toByteArray(response.getEntity());
//				File f =new File("img.png");
//				OutputStream os = new FileOutputStream(f);
//				os.write(bs);
//				os.close();
////				return EntityUtils.toString(response.getEntity());
//				return f.getAbsolutePath();
//			} finally {
//			    response.close();
//			}
//		} catch (ClientProtocolException e) {
//			e.printStackTrace();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//		return null;
//	}
//	//http post
//	public static String post(String url, Object ... kvs){
//		try {
//			List formparams = new ArrayList();
//			for(int i = 0;i < kvs.length/2; i++){
//				formparams.add(new BasicNameValuePair(""+kvs[2*i], ""+kvs[2*i + 1]));
//			}
//			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
//			HttpPost post = new HttpPost(url);
//			post.setEntity(entity);
//			
//			CloseableHttpClient httpclient = HttpClients.createDefault();
//			CloseableHttpResponse response = httpclient.execute(post, context);
//			try {
////				System.out.println(response);
//				return EntityUtils.toString(response.getEntity());
//			} finally {
//			    response.close();
//			}
//		} catch (ClientProtocolException e) {
//			e.printStackTrace();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//		return null;
//	}
//	
//	//http post
//		public static String postString(String url, String str){
//			try {
//				StringEntity sentity = new StringEntity(str, Consts.UTF_8);
//				HttpPost post = new HttpPost(url);
//				post.setEntity(sentity);
//				
//				CloseableHttpClient httpclient = HttpClients.createDefault();
//				CloseableHttpResponse response = httpclient.execute(post, context);
//				try {
////					System.out.println(response);
//					HttpEntity ent = response.getEntity();
//					String res = "";
//					try {
//						res = EntityUtils.toString(ent, Charset.forName("UTF-8"));
//					} catch (ParseException e) {
//						e.printStackTrace();
//						res = null;
//					}
//					return res;
//				} finally {
//				    response.close();
//				}
//			} catch (ClientProtocolException e) {
//				e.printStackTrace();
//			} catch (IOException e) {
//				e.printStackTrace();
//			}
//			return null;
//		}
}

 

你可能感兴趣的:(网页版本微信通讯协议分析)