Java實現二維碼掃碼授權登陸
阿新 • • 發佈:2019-01-28
假設現在有2個裝置,A裝置需要掃碼授權登陸,B裝置是已經登陸了的裝置。然後實現如下:
一:A裝置生成生成二維碼:
A裝置向伺服器請求getLoginCode介面,這個介面根據請求的sessionId進行base64或其他加密方式進行加密,然後以此作為二維碼的值,並將這個loginCode寫到redis裡,設定5分鐘過期。然後將這個loginCode返回給A裝置,A裝置以此值來生成登陸的二維碼。
二:B裝置掃碼授權
B裝置來掃A裝置的二維碼的時候,攜帶二維碼的值,請求授權登陸的介面scanConfirmLogin,此接口裡先校驗二維碼是否過期,沒過期的話進行後面的業務邏輯處理,將使用者的基本資訊和token寫到redis裡。
三:A裝置輪詢獲取授權狀態
B裝置以每秒一次的頻率來刷 獲取使用者授權狀態介面,若狀態為已授權,拿到使用者資訊去做後面的邏輯處理。
/** * 獲取掃描登陸的二維碼 * @param noncestr隨機字串 * @throws Exception */ @RequestMapping(value = "user/getLoginCode.json") public void getLoginCode(String noncestr,HttpServletRequest request,HttpServletResponse response) throws Exception { if(StringUtil.isBlank(noncestr)){ apiData(request, response,ReqJson.error(CommonError.PARAMS_IMPERFECT)); return; } //引數的有效性校驗在攔截器裡實現 int expirationTime=300; //時效5分鐘 final String sessionId=request.getSession().getId(); String loginCode=ToolUtils.getBase64(sessionId); JedisUtil.set(loginCode, loginCode, expirationTime); Map<String,Object> map=new HashMap<>(); map.put("loginCode", loginCode); map.put("expirationTime", expirationTime); apiData(request, response, ReqJson.ok(map)); } /** * 掃碼確認登陸 * @param loginCode * @param request * @param response * @throws Exception */ @RequestMapping(value = "user/scanConfirmLogin.json") @AuthorizationApi public void scanConfirmLogin(@CurrentToken final Token token,String loginCode,HttpServletRequest request,HttpServletResponse response) throws Exception { if(StringUtil.isBlank(loginCode)){ apiData(request, response,ReqJson.error(CommonError.PARAMS_IMPERFECT)); return; } String userId=token.getUserId(); Map<String,String> map=new HashMap<>(); String loginTicket=JedisUtil.get(loginCode); if(StringUtil.isBlank(loginTicket)){ //二維碼過期 apiData(request, response,ReqJson.error(CommonError.TWO_DIMENSIONAL_CODE_HAS_EXPIRED)); return; } UserInfo userInfo = userInfoBiz.getUser(new UserInfo(userId)); if(userInfo==null){ apiData(request, response,ReqJson.error(UserError.USER_NOT_FOUND)); return; } //將使用者資訊放在快取中 map.put(BaseConfig.ACCESS_TOKEN, token.getAccessToken()); map.put("userId", userInfo.getUserId()); map.put("rongCloudToken", userInfo.getRongCloudToken()); map.put("identity", userInfo.getIdentity()); JedisUtil.setMap(loginCode+"scanConfirmLogin", map, 300); apiData(request, response, ReqJson.ok(new Object())); } /** * 獲取登陸狀態 * @param loginCode * @param request * @param response * @throws Exception */ @RequestMapping(value = "user/getScanConfirmLoginStatus.json") public void getLoginStatus(final String loginCode,HttpServletRequest request,HttpServletResponse response) throws Exception { if(StringUtil.isBlank(loginCode)){ apiData(request, response,ReqJson.error(CommonError.PARAMS_IMPERFECT)); return; } Map<String,String> map= JedisUtil.getMap(loginCode+"scanConfirmLogin"); if(map==null){ apiData(request, response,ReqJson.error(CommonError.AUTHORIZATION_HAS_EXPIRED)); return; } apiData(request, response, ReqJson.ok(map)); }