基于jwt的用户登录认证

最近在app的开发过程中,做了一个基于token的用户登录认证,使用vue+node+mongoDB进行的开发,前来总结一下。

token认证流程:

1:用户输入用户名和密码,进行登录操作,发送登录信息到服务器端。

2:服务器端查询数据库验证用户名密码是否正确,正确,通过jsonwebtoken生成token,返回给客户端;否则返回错误信息给客户端。

3:通过本地存储存储获取的token信息,并且会跳转到路由指定的页面。

4:当客户端需要请求数据时,发送请求,并且在请求的头文件中添加本地存储的token信息。

5:服务器端获取到请求头文件中的token信息,解析token信息,验证是否有效,有效,查询数据库,返回请求的数据。

客户端与服务器端关于token的验证示意图:

1:用户登录的模型骨架文件user.js

‘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.js

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
    }, ‘[email protected]‘, {
        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, ‘[email protected]‘);
        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)
                    });
            },

  

   

原文地址:https://www.cnblogs.com/sk-3/p/9188168.html

时间: 2024-10-10 06:11:14

基于jwt的用户登录认证的相关文章

Java秒杀系统实战系列~整合Shiro实现用户登录认证

摘要: 本篇博文是"Java秒杀系统实战系列文章"的第五篇,在本篇博文中,我们将整合权限认证-授权框架Shiro,实现用户的登陆认证功能,主要用于:要求用户在抢购商品或者秒杀商品时,限制用户进行登陆!并对于特定的url(比如抢购请求对应的url)进行过滤(即当用户访问指定的url时,需要要求用户进行登陆). 内容: 对于Shiro,相信各位小伙伴应该听说过,甚至应该也使用过!简单而言,它是一个很好用的用户身份认证.权限授权框架,可以实现用户登录认证,权限.资源授权.会话管理等功能,在本

radhat Linux 用户登录认证失败

今天客户反映一个问题,ssh不上自己的服务器了,进机房radhat linux本地登录(3级别)的时候发现输入root敲回车的时候出现如下提示: Your account is locked.Maximum amount of failed attempts was reached. 好说,单用户模式下 pam_tally2 -u root  (faillog -u root<查看/var/log/faillog内记录的登陆失败信息>)显示root用户登录失败记录的次数 pam_tally2

【web开发】★☆之基于Map实现(用户登录三次失败后)24小时之内限制登录!

[web开发]★☆之基于Map实现(用户登录三次失败后)24小时之内限制登录! 近期在改一个老项目(struts1做的),客户现在想实现如下效果,用户在登录失败三次之后,锁定用户,需要信息部管理人员进行解锁!我第一想法,是在其数据库User表中加一个字段,记录登录失败的次数,但是数据库添加字段需要远程操作数据库,而对方的数据库又被各种加密软件包围!不是很方便,所以想了一下解决方案,利用Map来进行处理! 首先说一个思路,新建实体类,只有两个属性,登录失败次数,登录时间,实现get,set方法!

OpenVPN 实战3:OpenVPN+MySQL 实现用户登录认证

大纲 一.前言 二.概述 三.具体配置过程 四.总结 注,实战环境 CentOS 5.5 x86_64,软件版本 OpenVPN 2.1,软件下载:http://yunpan.cn/QzT8fGsX8S75a  访问密码 e8e4. 一.前言 在上一篇博客中我们提出一个问题,下面我们来回顾一下: 前面做的实验都是由服务端先生成客户端证书,然后分发到客户端上,让客户端通过证书连接到服务器上.但有时候,这样的分发是比较麻烦的(也不安全).这样,我们可以考虑另外一种方式: 只在服务端制作客户端证书,而

手把手教你学会 基于JWT的单点登录

??最近我们组要给负责的一个管理系统 A 集成另外一个系统 B,为了让用户使用更加便捷,避免多个系统重复登录,希望能够达到这样的效果--用户只需登录一次就能够在这两个系统中进行操作.很明显这就是单点登录(Single Sign-On)达到的效果,正好可以明目张胆的学一波单点登录知识. 本篇主要内容如下: SSO 介绍 SSO 的几种实现方式对比 基于 JWT 的 spring boot 单点登录实战 注意: ??SSO 这个概念已经出现很久很久了,目前各种平台都有非常成熟的实现,比如OpenSS

linux PAM 用户登录认证

PAM(Pluggable Authentication Modules )是由Sun提出的一种认证机制.它通过提供一些动态链接库和一套统一的API,将系统提供的服务 和该服务的认证方式分开,使得系统管理员可以灵活地根据需要给不同的服务配置不同的认证方式而无需更改服务程序,同时也便于向系 统中添加新的认证手段.从本篇开始会总结一些常用的pam模块及其实现的功能,今天讲的是pam_tally2模块. 一.参数与场景 应用场景:设置Linux用户连续N次输入错误密码进行登陆时,自动锁定X分钟或永久锁

PPTP-VPN第二章——使用mysql进行用户登录认证

在上一篇文章中记录了pptp vpn的创建过程和简单实用测试,其中用户名和密码均使用文本数据库/etc/ppp/chap-secrets,小规模用户下,尚可使用这种登陆验证方式,如果用户数多了,则需要将用户登录验证方式修改为查询数据库,在本文中将介绍如何将pptp vpn的用户名和密码认证信息存储在mysql数据库中. 前文传送门:http://ylw6006.blog.51cto.com/470441/1794577 一.安装和配置整合mysql-server和freeradius,和前文一样

关于django用户登录认证中的cookie和session

最近弄django的时候在用户登录这一块遇到了困难,网上的资料也都不完整或者存在缺陷. 写这篇文章的主要目的是对一些刚学django的新手朋友提供一些帮助.前提是你对django中的session和cookie已经有了一定的了解. 我最基本的设想是当用户登陆了网站后,用户访问本网站的其他网页时依旧能识别其身份. 很多教程的方法是在用户的cookie中存储用户名,这种方法当然是非常不安全的. 其实只要我们使用了django中的session,django就会自动在用户的cookie中存储 sess

shiro用户登录认证

1.用户访问服务器 2.过滤器过滤所有访问的资源,判断用户是否认证  目标位置在这里是登录验证的controller 用户登录没有认证会跳转到这个方法,此方法只判断错误信息,如果错误,会把mv打回到登录页面并显示消息:如果是正确信息,默认会调用过滤器中的回到上一个请求的页面,也就是访问网站的index页面. 3.首次登录没有session,没有认证,跳转到login页面 前端 后台 login.jsp 必须这样写: 原因:之前配置了过滤器,表单过滤器默认了参数名,不能随意更改,包括上面的异常信息