HelloWorld -- 掃碼登錄(客戶端輪訓)

掃碼登錄-客戶端定時器輪訓實現(xiàn)

源碼地址:https://gitee.com/HQSONG/helloworld.git

controller接口

詳細可參考源代碼只嚣。cn.codersnet.helloworld.scanlogin.web.ScanLoginController

@RestController
@RequestMapping("/scanlogin")
public class ScanLoginController {

    private Log logger = LogFactory.getLog(this.getClass());
    
    private static final String TOKEN_LOGINID_SUFFIX = "_loginID";
    @Autowired
    private Cache cache;
    
    /**
     * 生成二維碼桩撮,暫時返回token
     * @return
     */
    @GetMapping("/generate")
    public String generateCrCode() {
        //生成token
        String token = UUID.randomUUID().toString();
        //將token置于緩存中沼沈,可以設置默認有效期珍昨,可以直接使用redis緩存設置過期時間挂洛。這里簡單通過map實現(xiàn)
        cache.put(token, new ScanStatus(ScanStatus.CODE_GENERATE, "二維碼已生成, 待掃描"), 60); //60s后過期
        return token;
    }
    
    /**
     * 移動端掃碼
     * @return
     */
    @GetMapping("/appScan")
    public ScanStatus appScan(String token) {
        
        ScanStatus status = new ScanStatus(ScanStatus.CODE_SCANED, "二維碼已掃描, 待確認");
        if(cache.existed(token)) {
            cache.put(token, status);
        } else {
            status.setStatusCode(ScanStatus.CODE_EXPIRED);
            status.setMessage("二維碼已過期或不存在");
        }
        return status;
    }
    
    /**
     * 移動端確認登錄佩谣,如果存在token未過期凡怎,設置token和loginID關聯(lián)關系
     * @param token
     * @param loginID
     * @return
     */
    @GetMapping("/appConfirm")
    public ScanStatus appConfirm(String token, String loginID) {
        ScanStatus status = new ScanStatus(ScanStatus.CODE_APP_CONFIRM, "移動端已確認");
        if(cache.existed(token)) {
            cache.put(token, status);
            cache.put(token + TOKEN_LOGINID_SUFFIX, loginID);
        } else {
            status.setStatusCode(ScanStatus.CODE_EXPIRED);
            status.setMessage("二維碼已過期或不存在");
        }
        return status;
    }
    
    /**
     * 檢查掃碼狀態(tài)
     * @param token
     * @return
     */
    @PostMapping("/check")
    public ScanStatus check(String token) {
        
        if(cache.existed(token)) {
            ScanStatus scanStatus = (ScanStatus)cache.get(token);
            if(ScanStatus.CODE_APP_CONFIRM == scanStatus.getStatusCode()) {
                //TODO 執(zhí)行登錄
                String loginID = (String)cache.get(token + TOKEN_LOGINID_SUFFIX); 
                logger.info(loginID + ", app掃描登錄成功");
                return new ScanStatus(ScanStatus.CODE_LOGIN_SUCCESS, "登錄成功");
            } else {
                return scanStatus;
            }
        } 
        //二維碼過期
        cache.remove(token + TOKEN_LOGINID_SUFFIX);
        return new ScanStatus(ScanStatus.CODE_EXPIRED, "二維碼已過期或不存在");
    }
}

單元測試

詳細可參考源代碼悉稠。cn.codersnet.helloworld.ScanLoginTests

@RunWith(SpringRunner.class)
@SpringBootTest(classes = HelloworldApplication.class)
@AutoConfigureMockMvc
public class ScanLoginTests {

    @Autowired
    private MockMvc mvc;
    
    private JacksonTester<ScanStatus> json;

     @Before
     public void setup() {
         ObjectMapper objectMapper = new ObjectMapper();
         JacksonTester.initFields(this, objectMapper);
     }
    /**
     * 掃碼登錄測試測試方法
     * @throws Exception
     */
    @Test
    public void scanLoginSuccessTest() throws Exception {
        // 1. 獲取token(二維碼)
        String token = mvc.perform(get("/scanlogin/generate")).andReturn().getResponse().getContentAsString();
        Assert.isTrue(check(token).getStatusCode() == ScanStatus.CODE_GENERATE, "生成二維碼失敗");
        // 2. 移動端掃碼
        mvc.perform(get("/scanlogin/appScan").param("token", token));
        Assert.isTrue(check(token).getStatusCode() == ScanStatus.CODE_SCANED, "掃碼失敗");
        // 3. 移動端確認登錄
        mvc.perform(get("/scanlogin/appConfirm").param("token", token).param("loginID", "test01"));
        // 4. PC端登錄成功
        Assert.isTrue(check(token).getStatusCode() == ScanStatus.CODE_LOGIN_SUCCESS, "登錄失敗");
    }
    /**
     * 掃碼登錄超時測試方法宫蛆,示例代碼中超時時間為60s
     * @throws Exception
     */
    @Test
    public void scanLoginTimeoutTest() throws Exception {
        // 1. 獲取token(二維碼)
        String token = mvc.perform(get("/scanlogin/generate")).andReturn().getResponse().getContentAsString();
        Assert.isTrue(check(token).getStatusCode() == ScanStatus.CODE_GENERATE, "生成二維碼失敗");
        //2. 等待超時
        Thread.sleep(60*1000);
        //3. PC端check驗證
        Assert.isTrue(check(token).getStatusCode() == ScanStatus.CODE_EXPIRED, "超時校驗失敗");
        //4. 移動端掃碼驗證
        mvc.perform(get("/scanlogin/appScan").param("token", token));
        Assert.isTrue(check(token).getStatusCode() == ScanStatus.CODE_EXPIRED, "超時校驗失敗");
    }
    

    private ScanStatus check(String token) throws Exception {
        String checkStr = mvc.perform(post("/scanlogin/check").param("token", token)).andReturn().getResponse()
                .getContentAsString();
        return this.json.parseObject(checkStr);
    }

}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市的猛,隨后出現(xiàn)的幾起案子耀盗,更是在濱河造成了極大的恐慌,老刑警劉巖卦尊,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叛拷,死亡現(xiàn)場離奇詭異,居然都是意外死亡岂却,警方通過查閱死者的電腦和手機忿薇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來躏哩,“玉大人署浩,你說我怎么就攤上這事∩ǔ撸” “怎么了筋栋?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長正驻。 經(jīng)常有香客問我弊攘,道長,這世上最難降的妖魔是什么姑曙? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任襟交,我火速辦了婚禮,結果婚禮上伤靠,老公的妹妹穿的比我還像新娘婿着。我一直安慰自己,他們只是感情好醋界,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布竟宋。 她就那樣靜靜地躺著,像睡著了一般形纺。 火紅的嫁衣襯著肌膚如雪丘侠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天逐样,我揣著相機與錄音蜗字,去河邊找鬼打肝。 笑死,一個胖子當著我的面吹牛挪捕,可吹牛的內(nèi)容都是我干的粗梭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼级零,長吁一口氣:“原來是場噩夢啊……” “哼断医!你這毒婦竟也來了?” 一聲冷哼從身側響起奏纪,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤鉴嗤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后序调,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體醉锅,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年发绢,在試婚紗的時候發(fā)現(xiàn)自己被綠了硬耍。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡边酒,死狀恐怖默垄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情甚纲,我是刑警寧澤口锭,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站介杆,受9級特大地震影響鹃操,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜春哨,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一荆隘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赴背,春花似錦椰拒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至便瑟,卻和暖如春缆毁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背到涂。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工脊框, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留颁督,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓浇雹,卻偏偏與公主長得像沉御,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子昭灵,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Home 關于Gitee Gitee 是開源中國社區(qū)[http://www.oschina.net]團隊基于開源項...
    奮拓達閱讀 2,263評論 0 3
  • “爸爸柱徙,怎樣才能不讓城堡里的水流走啊奇昙? ” 沙灘上护侮,小朋友挖著小城堡,但很快發(fā)現(xiàn)储耐,城堡里的水在不斷向外滲出羊初。他本不...
    磨嘰的磨驢閱讀 471評論 6 8
  • “需要時,組織應采用適當?shù)姆椒ㄗR別輸出什湘,以確保產(chǎn)品和服務合格长赞。組織應在生產(chǎn)和服務提供的整個過程中按照監(jiān)視和測量要求...
    賽德傳播閱讀 1,620評論 0 0
  • 前幾天在街上閑逛蕩,看著人來人往闽撤,哼著小曲唱著歌得哆,蹲在馬路牙子上,不時有帥哥經(jīng)過哟旗,心中做著評價贩据。格子襯衫,IT男闸餐;...
    死胖子zyr閱讀 194評論 0 0