express基於JWT實現使用者登陸授權

Joydezhong發表於2019-05-08

你是否和我一樣,在對接後端大佬的介面時,對於請求頭authorization認證感到疑惑;
你是否和我一樣,在向node後端領域擴充套件時,對於使用者登陸註冊授權感到撓頭;
你是否和我一樣,在瀏覽器訪問某個頁面時,對於訪問許可權控制感到好奇;
那麼,請花上幾分鐘時間閱讀,讓下文來幫你解惑。

本文主要通過express來實現使用者登陸授權的邏輯,這裡的JWT只是一個標準,全稱:JSON Web Token。有興趣的小夥伴可以去這官網加深瞭解。

初始配置

初始化一個express專案,配置資料庫連線和載入bodyParser外掛。

//connect mongoDB
let mongoose = require('mongoose');
let mongoURL = 'mongodb://localhost/dataBase';
mongoose.connect(mongoURL);
mongoose.Promise = global.Promise;
let db = mongoose.connection;
db.on('error',console.error.bind(console, 'MongoDB connection error:'));

let bodyParser = require('body-parser');
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
複製程式碼

使用者註冊

編寫使用者model

用於連線資料庫的資料Schema模型

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var AuthSchema = new Schema({
    username: String,
    userpswd: String
});

// 引數:匯出模組名稱、Schema例項、資料表名稱
module.exports = mongoose.model('AuthInfo', AuthSchema, 'authinfo');
複製程式碼

編寫註冊route

基於restful API的介面路由

var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');

var mongoose = require('mongoose');
var AuthInfo = require('../models/authModel'); // 匯入model模組

router.post('/',function(req, res, next){
    console.log('open post register');

    var username = req.body.username;
    var password = req.body.password;

    //是否合法的引數
    if (username == null || username.trim() == '' || password == null || password.trim() == '') {
        res.send({code: 500, message: '使用者名稱密碼不能為空'})
        return
    }
    
   // md5
    var md5String = require('crypto').createHash('md5').update(password).digest('hex');

    //驗證賬號是否存在
    var queryString = {username: username};
    res.set({'Content-type': 'application/json;charset=utf-8'});

    AuthInfo.findOne(queryString).then(data => {
        return new Promise((resolve, reject)=>{
            if(data){
                res.send({code: 500, message: '使用者已經註冊'});
                reject();
            }else{
                resolve();
            }
        }).then(()=>{
            //儲存
            return new AuthInfo({
                username: username,
                password: md5String
            }).save();
        }).then(data => {
            if(data){
                //返回
                res.send({code: 1, message: '註冊成功'})
                return;
            }
            // 返回
            res.send({code: 500, message: '註冊失敗'});
        }).catch(err => {
            // 異常
            if(err){
                res.status(500).send(err);
                console.log(err);
            }
        })
    })

});

module.exports = router;
複製程式碼

編寫登陸route

基於restful API的介面路由

var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');

var mongoose = require('mongoose');
var AuthInfo = require('../models/authModel');

router.post('/',function(req, res, next){

    var username = req.body.username;
    var password = req.body.password;

    //是否合法的引數
    if (username == null || username.trim() == '' || password == null || password.trim() == '') {
        res.send({code: 500, message: '使用者名稱密碼不能為空'})
        return
    }

    var md5String = require('crypto').createHash('md5').update(password).digest('hex'); // md5

    //驗證賬號是否存在
    var queryString = {username: username, userpswd: md5String};
    res.set({'Content-type': 'application/json;charset=utf-8'});
    
     // md5 token
    var tokenString = require('crypto').createHash('md5').update(JSON.stringify(queryString)).digest('hex');

    AuthInfo.findOne(queryString).then(data => {
        return new Promise((resolve, reject)=>{
            if(data){
               resolve(data);
            }else{
            	res.send({code: 500, message: '使用者名稱或密碼錯誤'})
              reject();
            }
        }).then(data => {
        		console.log(data);
        		res.send({ code: 1, message: '登陸成功', token: tokenString })
        })
    }).catch( err => {
    	if(err){
          res.status(500).send(err);
          console.log(err);
        }
    })

});

module.exports = router;
複製程式碼

這裡和註冊不同的是我們需要把從前端頁面接收到的密碼通過MD5轉換才能用於資料庫查詢,因為資料庫的密碼欄位也正是存著MD5轉換過後的字元,當查詢成功之後,我們還需要通過對剛才登陸的表單欄位物件進行字串轉換,然後再通過MD加密後作為token返回給客戶端。

本文參考:juejin.im/post/5c2a2f…

相關文章