天天看點

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入

上篇文章使用了bcryptjs對密碼進行了加密,既然加密後的密碼是不可逆的,那麼儲存後的密文又如何被驗證識别呢?

仍然使用bcryptjs,其中的compareSync來比較密碼和資料庫的密文。

1.制作登陸頁面

登陸頁面不使用Main.vue帶有左側菜單的布局,是以與Main.vue的路由連結“/”同級。

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入
Login.vue:

<template>
    <div class="login-container">
        <el-card header="管理者登入" class="login-card">
            <!-- 監聽表單的submit事件,native.prevent監聽原生表單事件跳轉接口并且阻止頁面跳轉 -->
            <el-form @submit.native.prevent="login">
                <el-form-item label="使用者名">
                    <el-input v-model="model.username"></el-input>
                </el-form-item>
                <el-form-item label="密碼">
                    <el-input v-model="model.password" type="password"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" native-type="submit">登入</el-button>
                </el-form-item>
            </el-form>
        </el-card>
    </div>
</template>

<script>
export default {
    data() {
        return {
            model: {}
        }
    },
    methods: {
        async login() {
            const res = await this.$http.post('login')
            console.log(res)
        }
    }
}
</script>

<style>
.login-card{
    width: 35rem;
    margin: 6rem auto;
}
</style>           

2.寫登入接口

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入

server/routes/admin/index.js:

// 登入接口

    app.post('/admin/api/login', async(req, res) => {
        // 将接收到的username和password解構
        const { username, password } = req.body

        // 1.根據使用者名找使用者
            // 如果使用者名為空
        if(!username){
            return res.status(422).send({
                message: '請輸入使用者名'
            })
        }
            // 引入model模型
        const Admin = require('../../models/Admin')
            // 利用模型查找指定使用者,同時将密碼連帶查詢出來
        const user = await Admin.findOne({
            username: username
        }).select('+password')
        if(!user){
            // 如果沒有該使用者,傳回一個非500\404的錯誤碼,同時發送查詢結果不存在的資訊
            return res.status(422).send({
                message: '使用者不存在'
            })
        }

        // 2.校驗密碼
        if(!password){
            return res.status(422).send({
                message: '請輸入密碼'
            })
        }
            // 引入bcryptjs,用來比較密碼和密文是否比對(前端傳入的password,後端查詢資料庫的password)
        const isValid = require('bcryptjs').compareSync(password, user.password)
            // 如果密碼與密文不比對
        if(!isValid){
            return res.status(422).send({
                message: '密碼錯誤'
            })
        }
        
        // 3.傳回token
            // 如果密碼與密文比對
        return ..
    })           

測試:

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入

3.全局監聽響應的攔截,将錯誤時發送的message在頁面顯示

admin/src/http.js:

// 全局進行響應的攔截(axios内的響應攔截方法)
http.interceptors.response.use(res => {
    return res
},err => {
    // 如果攔截到錯誤的操作,使用VUE将錯誤資訊進行彈出展示
    // 擷取錯誤資訊console.log(err.response.data.message)
    Vue.prototype.$message({
        type: 'error',
        message: err.response.data.message
    })
    return Promise.reject(err)
})           
技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入
技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入

4.使用jsonwebtoken建立token值進行登入

密碼驗證成功後,我們就向admin端發送一個token值,像session一樣挂載到網頁,如果有token值就可以進入admin頁面,沒有就需要進行登入。

(1)使用token

cd server           
npm i jsonwebtoken           
技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入

在server/routes/admin/index.js登入接口第三步,生成密鑰處編寫:

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入

server/index.js全局定義密鑰:

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入

此時,點選登入token值就可以生成,并發送到web端:

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入

(2)存儲token并跳轉admin管理頁面

Login.vue編輯login接口回調:

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入
技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入

登陸成功。

且token值已儲存:

技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-2.管理者登入

5.token驗證

此時我們已經完成了管理者登入功能的實作,但是就算不登陸也可以通路admin端頁面,下篇文章我們使用token進行登陸的校驗,實作進入頁面必須登入的操作。