基於jwt的用戶登陸認證

最近在app的開發過程當中,作了一個基於token的用戶登陸認證,使用vue+node+mongoDB進行的開發,前來總結一下。javascript

token認證流程:vue

1:用戶輸入用戶名和密碼,進行登陸操做,發送登陸信息到服務器端。java

2:服務器端查詢數據庫驗證用戶名密碼是否正確,正確,經過jsonwebtoken生成token,返回給客戶端;不然返回錯誤信息給客戶端。node

3:經過本地存儲存儲獲取的token信息,而且會跳轉到路由指定的頁面。ios

4:當客戶端須要請求數據時,發送請求,而且在請求的頭文件中添加本地存儲的token信息。web

5:服務器端獲取到請求頭文件中的token信息,解析token信息,驗證是否有效,有效,查詢數據庫,返回請求的數據。數據庫

客戶端與服務器端關於token的驗證示意圖:express

 

1:用戶登陸的模型骨架文件user.jsjson

'use strict';

let mongoose = require('mongoose'),
	Schema = mongoose.Schema;
	
let userSchema = new Schema({
	"username": String,
	"password": String,
	"token": String,
    	"create_time": Date
    });

let users = mongoose.model('users', userSchema);

module.exports = users;

2:服務器端api請求文件api.jsaxios

const express = require('express');
const router = express();
const db=require('../db/db.js');
const User=require('../db/user.js');
const Login=require('../db/login.js');
const Fan=require('../db/fan.js');
const Power=require('../db/power.js');
const createToken = require('../token/createToken');
const checkToken = require('../token/checkToken');

// 註冊
router.post('/add', function(req, res, next){
	let username = req.body.username,
		password = req.body.password;
	let newUser = new User({
		username: req.body.username,
		password: req.body.password
	});
	User.findOne({"username":username},(err, result) => {
		if(err){
			console.log('error:' + err);
			return;
		}
		console.log('result:',result);
		if(!result){
			newUser.save(function(err, result){
				if(err){
					console.log('error:' + err);
					return;
				}
				res.send({success: true, msg: '註冊成功'});
			});
		}else{
			res.send({success: false, msg: '用戶名已經存在'});
		}
	});
});

// 登陸
router.post('/login', function(req, res, next){
	let username = req.body.username,
		password = req.body.password;
	
	User.findOne({"username":username},(err, result) => {
		if(err){
			res.send({success: false, msg: '用戶名不存在'})
			console.log('error:' + err);
			return;
		}
		console.log('result:',result)
		if(result.password === password){
			console.log('登陸成功')
               // 調用token生成函數 let _token = createToken(username); // 保存token到數據庫中 result.token = _token; result.save((err) => { if(err){ console.log('error:' + err + 'token') } }) if(result){ res.send({success: true, msg: '登陸成功', token: _token}); }else{ res.send({success: false, msg: '登陸失敗'}); } }else{ res.send({success: false, msg: '密碼錯誤'}); } }); }); // token router.post('/createtoken', function(req, res, next){ let username = req.body.username; User.findOne({"username":username},(err, result) => { if(err){ res.send({success: false, msg: '用戶名不存在'}) console.log('error:' + err); return; } console.log('result:',result) let token = createToken(username); result.token = token; result.save((err) => { if(err){ console.log('error:' + err + 'token') } }) if(result){ res.send({success: true, msg: '登陸成功', token: token}); }else{ res.send({success: false, msg: '登陸失敗'}); } }); }); // 刪除用戶
// 刪除用戶時,驗證token信息是否過時 router.get('/delete', checkToken, function(req, res, next){ let _username = req.body.username; User.remove({username: _username}, (err, result) => { if(err){ console.log('error:' + err); return; } res.send(result); }); }); module.exports = router;

3:服務器端token生成文件createToken.js

const jwt = require('jsonwebtoken');


module.exports = function(user_id){
    const token = jwt.sign({
        user_id: user_id
    }, '1025886304@qq.com', {
        expiresIn: 60  //過時時間設置爲60
    });
    return token;
};

4:服務器端驗證token是否正確文件checkToken.js

const jwt = require('jsonwebtoken');
//檢查token是否過時

module.exports = function(req, res, next) {
   // 獲取請求頭文件中的token信息 let token = req.body.token || req.query.token || req.headers['authorization']; console.log(token) // 解析 token if (token) { // 確認token是否正確 let decoded = jwt.decode(token, '1025886304@qq.com'); console.log(decoded,44444)
// 驗證token是否過時 if(token && decoded.exp <= new Date()/1000){ return res.json({ success: false, message: 'token過時' }); }else{ return next(); } } else { // 若是沒有token,則返回錯誤 return res.status(403).send({ success: false, message: '沒有提供token!' }); } };

5:服務器端啓動文件

const express = require("express");
var bodyParser=require('body-parser');
const app = express();
const api = require('./router/api')

// 跨域設置
app.all("*", function(req, res, next) {
	res.header("Access-Control-Allow-Credentials", true);
	res.header("Access-Control-Allow-Origin", "*");
	res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
	res.header("Content-Type", "application/json;charset=utf-8");
	// 設置請求頭類型 添加token res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
	next();
});

app.use(bodyParser.urlencoded({extended:true}));

app.use("/api", api);

app.get('/', (req, res) => {
	res.send('Hello World');
});

const port = process.env.PORT || 3001;

app.listen(port, () => {
	console.log('Express server listening on port ' + port);
});

module.exports = app;

 

6:vue中用戶登陸操做

login () {
    let params = new URLSearchParams();
    params.append('username', this.login_username);
    params.append('password', this.login_password);
    let _token = localStorage.getItem('token');
    let that = this;
    console.log(_token)
    axios.post('http://localhost:3001/api/login', params, {headers:{'Content-Type':'application/x-www-form-urlencoded','Authorization': _token}})
         .then(function(res){
             console.log(res)
             if(res.data.success){
                 let token = res.data.token;
                 localStorage.setItem('token', token);
                 that.$router.push({
                     path: '/index'
                 })
             }
                    })
                    .catch(function(err){
                        console.log(err)
                    });
            },
相關文章
相關標籤/搜索