1. 程式人生 > >javaweb實現app掃碼登入

javaweb實現app掃碼登入

1.web頁面主動向伺服器索要一張由伺服器生成包含維一標識的二維碼圖片,也可以直接向後臺索要一個維一標識,拿到標識後通過js生成二維碼.這裡本人採用的是第二種方式,至於為什麼嗎,個人感覺這樣方便,後臺也不要匯入架包,最後將該標識存入List集合中,接下來會用到該標識


2.app掃碼後解析二維碼內的維一標識,然後再攜帶該標識跟使用者名稱發回給伺服器,伺服器接到請求後,遍歷List集合,驗證該標識是否為本系統生成的,若是再去驗證使用者名稱是否存在,若存在這時需將標識與使用者名稱繫結在一起
,繫結的方式有好多種,我這裡採用一種較為簡單的方法Map的方式,將標識做為key 使用者名稱做為value存在一個
全域性Map中,表示該使用者已經掃過碼了,只等接下來的驗證了


3.web頁面從向伺服器索取二維碼或標識後(第一步操作之後)就開始通過ajax每隔2秒或幾秒鐘
帶上維一標識向伺服器發起檢查請求,通過該標識檢視Map是否有對應的使用者已經掃過碼而未登入
有的話直接登入,沒有的話繼續輪尋,當然你也可以採用建立長連線的方式


4.以下為後臺程式碼 

package com.*;


@Controller
@RequestMapping(value = "/login")
public class LoginController{

	@Autowired
	private UserInfoBaseService userInfoBaseService;

	//儲存二維碼維一標識
	public static Set<String> tokes = new HashSet<>();
	//儲存toke繫結的使用者
	public static Map<String,String> 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
	 * @return
	 */
	@ResponseBody
	@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定時請求是否有使用者掃描了二維碼
	 * @param token
	 */
	@ResponseBody
	@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";
	}
	
}

5.以下為前臺程式碼
        //獲取維一標識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);