半暖商城第一季--再談登錄界面(六)

1. 前言

在第一季的第四篇教程中我留了一個坑,關(guān)于登錄界面的赐劣。在那篇教程中做登錄時無論成功還是失敗都會跳轉(zhuǎn)到另一個界面嫉拐,這個設(shè)計(jì)不能說不好,只能說不合適魁兼,用戶體驗(yàn)特別差婉徘。當(dāng)時說是以后會用Ajax技術(shù)重新寫的,本篇教程我們就來談?wù)勅绾问褂肁jax技術(shù)整出一個高逼格的登錄界面咐汞。

2. 使用Ajax技術(shù)實(shí)現(xiàn)一個登錄示例

在開始之前我們先來看一下最終實(shí)現(xiàn)的效果

登錄效果圖
登錄效果圖

有人可能會問盖呼,為什么無論是用戶名出錯了還是密碼出錯都只提示“用戶名或密碼有誤!”呢?其實(shí)在生產(chǎn)環(huán)境中如果你的提示太過細(xì)致化很有可能會招致暴力破解化撕,例如你用戶名通過了几晤,密碼出錯了,你提示“密碼有誤!”那不就等變相告訴別人用戶名是對的嗎植阴?所以在生產(chǎn)環(huán)境中我們的提示應(yīng)該模糊點(diǎn)兒不要太過細(xì)致蟹瘾。

如何實(shí)現(xiàn)?

首先用戶輸入用戶名和密碼墙贱,按登錄按鈕或者直接回車热芹,請求發(fā)出。

  1. 后臺接收到請求后將數(shù)據(jù)封裝成對象
  2. 拿個這個封裝好的對象執(zhí)行業(yè)務(wù)邏輯
  3. 返回執(zhí)行結(jié)果
  4. 前臺Ajax處理返回結(jié)果
  5. 提示用戶

步驟大致就是這樣惨撇。

先來看前臺代碼:

這是登錄表單

<div class="login-card">
    <div class="login-form">
        <h1 class="logo hide-text">半暖</h1>
        <form id="signInForm">
            <div class="group-inputs">
                <div class="input-wrapper account">
                    <input id="adminName" name="adminName" type="text" aria-label="請輸入用戶名" placeholder="請輸入用戶名"
                           required>
                </div>
                <div class="input-wrapper password">
                    <input id="password" name="password" type="password" aria-label="請輸入密碼" placeholder="請輸入密碼"
                           required>
                </div>
            </div>
            <div class="button-wrapper">
                <button id="signIn-button" name="signIn-button" type="button" class="signIn-button">登錄</button>
            </div>
        </form>
        <div id="message-info" class="message-info">
            <span id="message"></span>
        </div>
    </div>
</div>

兩個必填項(xiàng)一個登錄按鈕和一個錯誤信息提示框伊脓,很簡潔。

這是請求邏輯

<script src="<%=request.getContextPath()%>/static/js/jquery.min.js"></script>
<script type="text/javascript">

    $(function () {

        // 將錯誤信息提示框設(shè)為不可見
        $('#message-info').css('display', 'none');

        // 監(jiān)聽回車事件
        $('body').keydown(function (e) {
            if (e.keyCode == 13) {
                doLogin();
            }
        });

        // 監(jiān)聽登錄按鈕事件
        $('#signIn-button').click(function () {
            doLogin();
        });
    });

    // 登錄邏輯
    var doLogin = function () {
        $.ajax({
            // 請求發(fā)送方式
            type: 'post',
            // 請求地址
            url: '<%=request.getContextPath()%>/signIn',
            // 請求數(shù)據(jù)魁衙,用戶名和密碼
            data: {'adminName': $('#adminName').val(), 'password': $('#password').val()},
            // 異步报腔,不寫默認(rèn)為True
            async: false,
            // 請求成功后的回調(diào)
            success: function (signInResponse) {
                // 登錄成功狀態(tài)碼為 1
                if (signInResponse["success"] == 1) {
                    // 隱藏錯誤信息提示框
                    $('#message-info').css('display', 'none');
                    // 設(shè)置成功提示信息
                    $('#message').text(signInResponse["message"]);
                    // 跳轉(zhuǎn)到主頁
                    window.location.href = "<%=request.getContextPath()%>/main";
                } else if (signInResponse["success"] == 0) {
                    // 登錄失敗狀態(tài)碼為 0
                    // 設(shè)置錯誤提示信息
                    $('#message').text(signInResponse["message"]);
                    // 顯示錯誤提示框
                    $('#message-info').css('display', 'block');
                }
            },
            error: function (errorMessage) {
                // 其它錯誤信息
                $('#message').text(errorMessage);
                $('#message-info').css('display', 'block');
            }
        });
    }
</script>

實(shí)現(xiàn)過程已經(jīng)在代碼中注釋的很詳細(xì)了。

下面的是請求<%=request.getContextPath()%>/signIn地址后得到的Json數(shù)據(jù)剖淀,僅供參考

{
  "success": 1,
  "message": "登錄成功!",
  "administrator": null
}

后臺沒有傳入管理員信息纯蛾,原因是方式數(shù)據(jù)被劫持。其實(shí)前臺之需要判斷狀態(tài)就可以了纵隔,1就代表可以跳轉(zhuǎn)頁面了翻诉,0就代表登錄失敗。

以上代碼就可以實(shí)現(xiàn)登錄失敗時在當(dāng)前頁面顯示錯誤信息捌刮,登錄成功時跳轉(zhuǎn)到主頁了碰煌,但是我們是不是忘了啥?

3. 使用Session記錄登錄狀態(tài)

如果不在main界面判斷用戶是否登錄了绅作,那么是不是任何人鍵入main頁面的地址都可以訪問主頁了芦圾?如果是那樣那設(shè)置登錄頁面有個毛用?所以俄认,我們要在除了登錄頁面的其它頁面設(shè)置登錄狀態(tài)檢測

  1. 用戶登錄成功后設(shè)置Session信息
  2. 跳轉(zhuǎn)到除了登錄界面的其它界面時需要首先檢查登錄狀態(tài)
  3. 如果沒有登錄狀態(tài)則直接重定向到登錄界面

以上就是登錄的后續(xù)邏輯

我們再來分析个少,如果用戶打開了登錄界面是不是就代表需要重新登錄呢洪乍?所以,我們耍一個小聰明夜焦,在登錄界面的頭部添加以下代碼

<%
    session.invalidate();
%>

這行代碼的意思是清空Session數(shù)據(jù)壳澳。

只要用戶來到登錄頁面,就清空之前所有的Session數(shù)據(jù)糊探。

然后我們在除了登錄界面的其它界面添加以下代碼

<%
    Long adminId = (Long) session.getAttribute("adminId");
    String adminName = (String) session.getAttribute("adminName");
    Integer privilegeLevel = (Integer) session.getAttribute("privilegeLevel");
    if (null == adminId) {
        response.sendRedirect(request.getContextPath() + "/signIn");
        return;
    }
%>

這段代碼的意思是判斷當(dāng)前Session中是否存在‘a(chǎn)dminId’字段钾埂,之前我們說了,只要登錄成功就會寫入Session數(shù)據(jù)科平。

下面是登錄的接口

    /**
     * 管理員登錄接口
     *
     * @param session       會話
     * @param administrator 管理員信息
     * @return SignInResponse
     * @throws Exception 異常信息
     */
    public SignInResponse signIn(HttpSession session, Administrator administrator) throws Exception {

        SignInResponse response = new SignInResponse();

        Administrator administratorInfo = administratorMapper.verifyAdministratorByName(administrator);

        if (null != administratorInfo) {
            // 設(shè)置返回信息
            response.setSuccess(1);
            response.setMessage("登錄成功!");
            // 存儲Session
            session.setAttribute("adminId", administratorInfo.getAdminId());
            session.setAttribute("adminName", administratorInfo.getAdminName());
            session.setAttribute("privilegeLevel", administratorInfo.getPrivilegeLevel());
        } else {
            response.setSuccess(0);
            response.setMessage("用戶名或密碼有誤!");
        }

        return response;
    }

在主頁設(shè)置退出登錄的按鈕

<a href="<%=request.getContextPath()%>/signIn" class="btn btn-default btn-flat">退 出</a>

之需要在點(diǎn)擊退出按鈕的時候鏈接到登錄界面即可褥紫,因?yàn)榈卿浗缑嬖跍?zhǔn)備完成之前就已經(jīng)清空了Session數(shù)據(jù)了。

至此登錄界面完成瞪慧,喜歡的小伙伴記得關(guān)注哦髓考!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市弃酌,隨后出現(xiàn)的幾起案子氨菇,更是在濱河造成了極大的恐慌,老刑警劉巖妓湘,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件查蓉,死亡現(xiàn)場離奇詭異,居然都是意外死亡榜贴,警方通過查閱死者的電腦和手機(jī)豌研,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來唬党,“玉大人鹃共,你說我怎么就攤上這事∈还埃” “怎么了霜浴?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蓝纲。 經(jīng)常有香客問我阴孟,道長,這世上最難降的妖魔是什么税迷? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任永丝,我火速辦了婚禮,結(jié)果婚禮上翁狐,老公的妹妹穿的比我還像新娘。我一直安慰自己凌蔬,他們只是感情好露懒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布闯冷。 她就那樣靜靜地躺著,像睡著了一般懈词。 火紅的嫁衣襯著肌膚如雪蛇耀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天坎弯,我揣著相機(jī)與錄音纺涤,去河邊找鬼。 笑死抠忘,一個胖子當(dāng)著我的面吹牛撩炊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播崎脉,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拧咳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了囚灼?” 一聲冷哼從身側(cè)響起骆膝,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎灶体,沒想到半個月后阅签,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蝎抽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年政钟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片织中。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡锥涕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狭吼,到底是詐尸還是另有隱情层坠,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布刁笙,位于F島的核電站破花,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏疲吸。R本人自食惡果不足惜座每,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望摘悴。 院中可真熱鬧峭梳,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至孵运,卻和暖如春秦陋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背治笨。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工驳概, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人旷赖。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓顺又,卻偏偏與公主長得像,于是被迫代替她去往敵國和親杠愧。 傳聞我的和親對象是個殘疾皇子待榔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

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