java微信掃描公眾號(hào)二維碼實(shí)現(xiàn)登陸功能
本文實(shí)例為大家分享了java微信掃描公眾號(hào)二維碼實(shí)現(xiàn)登陸的具體代碼,供大家參考,具體內(nèi)容如下
前提條件:
1.微信公眾平臺(tái)為服務(wù)號(hào),
2.服務(wù)號(hào)實(shí)現(xiàn)了賬號(hào)綁定功能,即將open_id 與業(yè)務(wù)系統(tǒng)中的用戶名有對(duì)應(yīng)關(guān)系
具體實(shí)現(xiàn)原理:
1.用戶訪問業(yè)務(wù)系統(tǒng)登陸頁時(shí),調(diào)用二維碼接口,獲得二維碼的ticketid,同時(shí)將sessionid,ticketid和二維碼的seceneid保存
2.返回登陸頁時(shí),根據(jù)ticketid獲得微信二維碼
3.頁面通過ajax發(fā)送請(qǐng)求,判斷是否已經(jīng)掃描成功。
4.公眾平臺(tái)服務(wù)監(jiān)測到掃描事件,更新seceneid中掃描二維碼的業(yè)務(wù)系統(tǒng)用戶名
5.當(dāng)ajax監(jiān)測到掃描成功,并返回有業(yè)務(wù)系統(tǒng)用戶名,即可做模擬登陸!
具體代碼:
根據(jù)sceneID獲取,獲取ticketId, sceneId可以為sessionID,或者自定義的其他任何值,但必須保證不重復(fù)
注意:這里請(qǐng)求的type可以為臨時(shí)二維碼或永久二維碼,具體區(qū)別可以參看微信公眾平臺(tái)的開發(fā)者文檔。
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.掃描二維碼登陸的幾個(gè)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"/>
定時(shí)查詢掃描狀態(tài)
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.公眾平臺(tái)代碼
}else if(eventType.equalsIgnoreCase(MessageUtil.EVENT_TYPE_SCAN)){
String scene_id = eventKey;
if(Integer.parseInt(eventKey)==0){
respContent = "掃描參數(shù)出錯(cuò)!請(qǐng)刷新重試!";
}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 "您已成功登陸***系統(tǒng)!";
}
}
說明,框架使用jfinal 1.5
大家可以參考專題:java二維碼進(jìn)行學(xué)習(xí)
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
利用idea生成webservice客戶端超詳解步驟(wsdl文件的使用)
這篇文章主要給大家介紹了關(guān)于利用idea生成webservice客戶端超詳解步驟,第一次接觸webservice,從采坑到采坑,算是了解了一些,明白了一些,文中通過代碼以及圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12
MyBatis注解開發(fā)之實(shí)現(xiàn)自定義映射關(guān)系和關(guān)聯(lián)查詢
本文主要詳細(xì)介紹了MyBatis注解開發(fā)中,實(shí)現(xiàn)自定義映射關(guān)系和關(guān)聯(lián)查詢,文中有詳細(xì)的代碼示例,對(duì)學(xué)習(xí)MyBatis有一定的參考價(jià)值,需要的朋友可以參考閱讀2023-04-04
關(guān)于MyBatis plus條件構(gòu)造器的逐條詳解
什么是條件構(gòu)造器呢?簡單來說,條件構(gòu)造器就是用來生成我們查數(shù)據(jù)庫的sql。它可以簡化sql代碼的編寫,靈活、方便且易于維護(hù)2021-09-09
Java 兩種延時(shí)thread和timer詳解及實(shí)例代碼
這篇文章主要介紹了Java 兩種延時(shí)thread和timer詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02
下載遠(yuǎn)程maven倉庫的jar?手動(dòng)放到本地倉庫詳細(xì)操作
這篇文章主要介紹了如何下載遠(yuǎn)程maven倉庫的jar?手動(dòng)放到本地倉庫,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03
Java for循環(huán)性能優(yōu)化實(shí)現(xiàn)解析
這篇文章主要介紹了Java for循環(huán)性能優(yōu)化實(shí)現(xiàn)解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
Java新特性中Preview功能如何運(yùn)行調(diào)試詳解
這篇文章主要為大家介紹了Java新特性中Preview功能如何運(yùn)行調(diào)試詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10

