1.web頁面主動向伺服器索要一張由伺服器生成包含維一辨別的二維碼圖檔,也可以直接向背景索要一個維一辨別,拿到辨別後通過js生成二維碼.這裡本人采用的是第二種方式,至于為什麼嗎,個人感覺這樣友善,背景也不要導入架包,最後将該辨別存入List集合中,接下來會用到該辨別
2.app掃碼後解析二維碼内的維一辨別,然後再攜帶該辨別跟使用者名發回給伺服器,伺服器接到請求後,周遊List集合,驗證該辨別是否為本系統生成的,若是再去驗證使用者名是否存在,若存在這時需将辨別與使用者名綁定在一起
,綁定的方式有好多種,我這裡采用一種較為簡單的方法Map的方式,将辨別做為key 使用者名做為value存在一個
全局Map中,表示該使用者已經掃過碼了,隻等接下來的驗證了
3.web頁面從向伺服器索取二維碼或辨別後(第一步操作之後)就開始通過ajax每隔2秒或幾秒鐘
帶上維一辨別向伺服器發起檢查請求,通過該辨別檢視Map是否有對應的使用者已經掃過碼而未登入
有的話直接登入,沒有的話繼續輪尋,當然你也可以采用建立長連接配接的方式
4.前端代碼
//擷取維一辨別token生成二維碼
$.post('${ctx}/login/generationQRCode', function (token) {
new QRCode(document.getElementById('qrcode'), {text:token,height:125,width:125});
$('#qrcode').removeAttr('title');
$('#qrcode').attr('token',token);
});
//ajax定時檢視是否有使用者掃碼後未登入
var time = window.setInterval(function () {
var token = $('#qrcode').attr('token');
if(token){
$.post('${ctx}/login/scanLogin',{'token':token},function (data) {
if(data == 'success'){
clearInterval(time);
window.location.href = '${ctx}/login/';
}
})
}
},1000);
後端代碼
package com.*; @Controller@RequestMapping(value = "/login")public class LoginController{ @Autowiredprivate UserInfoBaseService userInfoBaseService; //存儲二維碼維一辨別public static Settokes = new HashSet<>();//存儲toke綁定的使用者public static Map users = new HashMap<>();
/**
* 生成二維碼維一辨別Toke
* @return
*/
@ResponseBody
@RequestMapping("/generationQRCode")
public String generationToken(){
String uid = UUID.randomUUID().toString();
tokes.add(uid);
return uid;
}
* app掃碼後将token與使用者綁定
* @param loginName
* @param token
@RequestMapping("/determine")
public ResponseEntity determine(String loginName, String token){
for (String t:tokes) {
if(t.equals(token)){
users.put(token,loginName);
UserInfo userInfo = userInfoBaseService.getUserByLoginName(loginName);
if(null==userInfo){return new ResponseFailure("使用者不存在");}
return new ResponseEntity("正在登入請稍後...");
}
}
return new ResponseEntity("請求無效");
* Axaj定時請求是否有使用者掃描了二維碼
@RequestMapping("/scanLogin")
public String scanLogin(String token){
if(StringKit.isBlank(token)){return "token is null";}
String loginName = users.get(token);
if(StringKit.isBlank(loginName)){ return "error";}
//Subject subject = SecurityUtils.getSubject(); //注釋的這三行換成你自已的登入代碼就行了
//subject.logout();
//UsernamePasswordTokenType tokenType = new UsernamePasswordTokenType(loginName, "123456",2);
try{
subject.login(tokenType);
}catch (Exception e){
e.printStackTrace();
users.remove(token);
tokes.remove(token);
return "success";
}