`
zhengshuo
  • 浏览: 134535 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

微信扫描公众号二维码实现登陆

阅读更多
前提条件:
1.微信公众平台为服务号,
2.服务号实现了账号绑定功能,即将open_id 与业务系统中的用户名有对应关系


具体实现原理:
1.用户访问业务系统登陆页时,调用二维码接口,获得二维码的ticketid,同时将sessionid,ticketid和二维码的seceneid保存
2.返回登陆页时,根据ticketid获得微信二维码
3.页面通过ajax发送请求,判断是否已经扫描成功。
4.公众平台服务监测到扫描事件,更新seceneid中扫描二维码的业务系统用户名
4.当ajax监测到扫描成功,并返回有业务系统用户名,即可做模拟登陆!

具体代码:
根据sceneID获取,获取ticketId,
sceneId可以为sessionID,或者自定义的其他任何值,但必须保证不重复
注意:这里请求的type可以为临时二维码或永久二维码,具体区别可以参看微信公众平台的开发者文档。
public static String getSceneTicket(String type,String sceneId){
		WxScene scene = new WxScene();
		scene.setAction_name(type);
		scene.setSceneId(Integer.parseInt(sceneId));
		scene.setExpire_seconds(1800);
		String jsonScene = JSONObject.fromObject(scene).toString();
		String url = WeixinContents.qr_scene_ticket_url.replaceAll("ACCESS_TOKEN", getAccessToken(WeixinContents.appid,WeixinContents.appsecret).getToken());
		System.out.println(jsonScene);
		JSONObject jsonObject = httpRequest(url, "POST", jsonScene);
		int result = 0;
		String ticket = "";
		if (null != jsonObject) {
			if (jsonObject.containsKey("errcode")) {
				result = jsonObject.getInt("errcode");
			}else{
				ticket = jsonObject.getString("ticket");
			}
		}
		return ticket;
	}


2.扫描二维码登陆的几个action
@ActionKey("/")
	@ClearInterceptor(ClearLayer.ALL)
	public void index() {
		LoginUser u = (LoginUser)getSessionAttr("LoginUser");
		setAttr("root", this.getRequest().getContextPath());
		if(null==u){
			setAttr("ticketId",wxTicket());
			render("/WEB-INF/login.html");
		}else{
			redirect("/index");
		}
	}
	private String wxTicket() {
		int sceneId = Db.queryInt("select SEQ_WX_SCENE.Nextval from dual");
		String ticketId = WeixinHttpUtils.getSceneTicket("QR_SCENE", sceneId+"");
		setSessionAttr("ticketId",ticketId);
		setSessionAttr("sessionId",this.getRequest().getSession().getId());
		String sql = "insert into wx_scence_logon(id,sessionid,ticketid,SCENCE_ID) values(sys_guid(),?,?,?)";
		Db.update(sql,this.getRequest().getSession().getId(),ticketId,sceneId);
		return ticketId;
	}
	@ActionKey("/cxTicket")
	@ClearInterceptor(ClearLayer.ALL)
	public void cxTicket(){
		String ticketId = getPara("ticketId");
		String sessionid = getPara("sessionId");
		int i=0;
		while(i<10){
			Record r = Db.findFirst("select id from wx_scence_logon l,wx_user u where u.open_id = l.open_id and l.ticketid = ? and l.sessionId = ?",ticketId,sessionid);
			if(r!=null&&StringUtils.isNotEmpty(r.getStr("id"))){
					setAttr("success","1");
					setAttr("logonId",r.getStr("id"));
					break;
			}else{
				setAttr("success","0");
				try {
					Thread.sleep(5000);
					i++;
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		render(new JsonRender().forIE());
	}
	@ActionKey("/ticketLogon")
	@ClearInterceptor(ClearLayer.ALL)
	public void ticketLogon(){
		String id = getPara("ticketId");
		Record r = Db.findFirst("select user_id as username from wx_scence_logon l,wx_user u where u.open_id = l.open_id and l.id = ?",id);
		if(r!=null&&StringUtils.isNotEmpty(r.getStr("username"))){
			String username = r.getStr("username");
			LoginUser user = LoginUser.dao.findFirst("select user_id,xm,department_id,departmentname,userpw from gy_user u where u.username = ? and u.userlockstate = '1' ",username);
			String permSql = "select distinct p.* from hr_user_role t,hr_role r,hr_role_perm m,hr_perms p where t.role_id = r.id and m.role_id = r.id and m.perm_id = p.id and user_id = ?";
			List<Record> perms = Db.find(permSql,new Object[]{user.getStr("user_id")});
			if(perms!=null&&perms.size()>0){
				this.getSession().removeAttribute("USER_PERMS");
				setSessionAttr("USER_PERMS",perms);
				getRequest().getSession().setAttribute("LoginUser",user);
			}
		}
		this.redirect("/main");
	}


3.
登陆页面
二维码显示
<img src="https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=${ticketId!}" width="250px"/>

定时查询扫描状态
function wxCxTikcet(){
	$.getJSON("${root!}/cxTicket",{ticketId:"${ticketId}",sessionId:"${sessionId}"},function(data){
		//alert(data.success=="1");
		if(data.success=='1'){
			_logon(data.logonId);
			//window.location.href="${root!}/ticketLogon/"+data.logonId;
		}
	});
}
var t_int = window.setInterval("wxCxTikcet()",5000);

4.公众平台代码

}else if(eventType.equalsIgnoreCase(MessageUtil.EVENT_TYPE_SCAN)){
							String scene_id = eventKey;
							if(Integer.parseInt(eventKey)==0){
								respContent = "扫描参数出错!请刷新重试!";
							}else{
								respContent = getSceneContent(scene_id,fromUserName);
							}
					}

private static String getSceneContent(String sceneId,String fromUserName){
		String sql ="select * from WX_SCENCE_LOGON  where scence_id = ?";
		Record r = Db.findFirst(sql,sceneId);
		if(r!=null){
			String updateSql = "update wx_scence_logon set open_id = ? where id = ?";
			Db.update(updateSql,fromUserName,r.getStr("id"));
			return "您已成功登陆***系统!";
		}
}




说明,框架使用jfinal 1.5
分享到:
评论
2 楼 fsh430623 2015-04-17  
有办法吗,我觉得扫描过后要是直接知道是哪个的二维码,多好
1 楼 fsh430623 2015-04-17  
为什么扫描二维码传过来的参数里取不到想要的场景Id信息呢
这不是很麻烦吗

相关推荐

    java微信扫描公众号二维码实现登陆功能

    主要为大家详细介绍了PHP微信扫描公众号二维码实现登陆功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    JS实现微信公众号Html5页面调用手机照相机识别二维码

    1、使用jweixin-1.4.0.js实现微信公众号Html5页面调用手机照相机识别二维码 2、核心代码已经给到txt文件中,可以根据需要自行扩充。 3、二维码可以由自己的API生成,应用到很多领域。

    nodejs实现带参微信公众号二维码进行事件推送

    结合了express+request+config+wechat等模块,实现了获取微信二维码url地址和ticket,事件推送服务

    C#微信开发带参数二维码

    C#代码微信开发 带参数二维码, 可用于不同渠道的推广宣传二维码制作。

    微信公众号真机调试(详细说明文档有截图)

    1.使用TBS Studio进行微信公众号真机调试扫描二维码报错无法安装线上TBS内核,原因是微信内置浏览器 x5内核以弃用升级到最新的xweb内核; 2.本方法是在最新版微信基础上真机公众号调试,手机电脑同屏利用浏览器的...

    .net微信公众号参数二维码模板消息

    8、扫描参数二维码接收参数和用户openid PS:代码仅供参考,需要在服务号上配置和获取 token,AppID,AppSecret,access_token以及设置网页OAuth2.0鉴权的网页地址。 全程几乎无验证,最好不要直接使用,建议完善验证...

    .NET C#使用微信公众号登录网站

    适用于:本文适用于有一定微信开发基础的用户  引言: 花了300大洋申请了微信公众平台后,发现不能使用微信公众号登录网站(非微信打开)获得微信帐号。仔细研究后才发现还要再花300大洋申请微信...2.用户通过微信扫描

    微信公众号二维码签到和抽奖软件

    【抽奖步骤】第1步:用户,通过链接或者扫描二维码签到第2步:管理员,查看签到列表第3步:管理员,电脑上打开“头像抽奖”抽奖【可以操作内容】第1步:准备好自己的APPID和APPSECRET(公众号的)第2步:打开WxAPI....

    PHPCMS微信小程序二维码导航网站模板源码.zip

    小程序可以通过扫描二维码  二维码或是搜一搜,就能立即使用。  可以进行关联,并相互跳转。通过公众号查看并进入所绑定的小程序一个公众号可以绑五个小程序。  小程序”可添加到桌面变成APP安卓用户可以将...

    微信公众号智能绑定实例

    微信公众号智能绑定实例,具体参考文章:... 如果后期微信公众号登录只能通过扫描二维码登录则智能绑定功能完全失效,目前企业号使用的就是扫描二维码+密码登录方式。

    公众号扫描带参数二维码实现分组

    微信公众号扫描带参数二维码实现自动分组,实现不同渠道进入用户数量统计,为地推用户进行绩效统计。

    微信测试公众号每日早安问候程序

    扫描测试号二维码后会生成微信号,哪个账号需要接收推送信息就需要哪个账号扫码 这里需要记住的是对应账号的微信号,也就是user id,后面需要用 ## 新增测试模板 这里点击`新增测试模板` 模板标题: 自定义,...

    PHP微信公众号接口开发在线调试工具 v2.0.zip

    3、受权限限制(全是个人未认证订阅号),暂未开发底部自定义菜单、关注者接口、二维码扫描事件等其他高级功能。 操作步骤: 1、直接上传并通过域名 目录访问,使用相对路径,支持任意目录直传即用。 PHP微信...

    PHP微信PC二维码登陆的实现思路

    另外看微信开发文档中存在一个scan事件,可以检测用户使用微信扫描二维码并获取值。其实问题的关键就在于这个值,这个值算是一个联通PC和微信的通信ID了。 二、具体实现流程(下面代码使用了TP5的框架,有个大前提是...

    asp微信公众号接口开发在线调试工具 V1.0

    受权限限制(全是个人未认证订阅号),暂未开发底部自定义菜单、关注者接口、二维码扫描事件等其他高级功能。 # 操作步骤 # #1. 直接上传并通过域名+目录访问,使用相对路径,支持任意目录直传即用。

    微信公众号接口在线调试工具PHP版.rar

     3、受权限限制(全是个人未认证订阅号),暂未开发底部自定义菜单、关注者接口、二维码扫描事件等其他高级功能。  使用方法:直接上传并通过域名 目录访问,使用相对路径,支持任意目录直传即用。

    asp微信公众号接口调试工具 v1.2.zip

    3. 受权限限制(全是个人未认证订阅号),暂未开发底部自定义菜单、关注者接口、二维码扫描事件等其他高级功能。 操作步骤 1. 直接上传并通过域名 目录访问,使用相对路径,支持任意目录直传即用。 asp微信公众号...

    Vue项目实战+PHP接口开发(微信扫码关注实现自动登陆)

    二、如何使用微信接口开发,如获取临时二维码,获取用户基础信息,监听公众号关注以及扫描事件 三、如何使用redis对数据进行缓存 四、如何使用php原生代码进行接口的开发 五、如何使用laralvel 7.x 框架进行接口...

    .netMVC框架微信公众号支付

    公众号支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付。...◆ 将商户页面转换成二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付

    微信扫一扫扫描二维码

    调用微信扫一扫接口,在自己的微信公众号里面实现扫描二维码功能。

Global site tag (gtag.js) - Google Analytics