本文实例为大家分享了java微信扫描公众号二维码实现登陆的具体代码,供大家参考,具体内容如下
前提条件:
1.微信公众平台为服务号,
2.服务号实现了账号绑定功能,即将open_id 与业务系统中的用户名有对应关系
具体实现原理:
1.用户访问业务系统登陆页时,调用二维码接口,获得二维码的ticketid,同时将sessionid,ticketid和二维码的seceneid保存
2.返回登陆页时,根据ticketid获得微信二维码
3.页面通过ajax发送请求,判断是否已经扫描成功。
4.公众平台服务监测到扫描事件,更新seceneid中扫描二维码的业务系统用户名
5.当ajax监测到扫描成功,并返回有业务系统用户名,即可做模拟登陆!
具体代码:
根据sceneID获取,获取ticketId, sceneId可以为sessionID,或者自定义的其他任何值,但必须保证不重复
注意:这里请求的type可以为临时二维码或永久二维码,具体区别可以参看微信公众平台的开发者文档。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
@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"/>
定时查询扫描状态
1
2
3
4
5
6
7
8
9
10
|
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/" rel="external nofollow" +data.logonId;
}
});
}
var t_int = window.setInterval( "wxCxTikcet()" ,5000);
|
4.公众平台代码
1
2
3
4
5
6
7
8
|
} else if (eventType.equalsIgnoreCase(MessageUtil.EVENT_TYPE_SCAN)){
String scene_id = eventKey;
if (Integer.parseInt(eventKey)== 0 ){
respContent = "扫描参数出错!请刷新重试!" ;
} else {
respContent = getSceneContent(scene_id,fromUserName);
}
}
|
1
2
3
4
5
6
7
8
9
|
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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。