当前位置: 首页 > 编程日记 > 正文

基于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}, '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)// 解析 tokenif (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");// 设置请求头类型 添加tokenres.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

相关文章:

跨平台网络游戏趋势和优势

跨平台网络游戏趋势和优势 前几年还是网页游戏蓬勃发展的状态&#xff0c;就有分析指出从明年开始网页游戏市场已经饱和&#xff0c;想想几年前客户端游戏也是同样的窘境&#xff0c;如果将桌面、移动设备、网页统称一个词汇的话&#xff0c;那就是终端&#xff0c;现在各种的终…

IAR生产HEX文件

刚刚接触IAR&#xff0c;编译默认生成的是.a90文件&#xff0c;但直接用avr studio下载时提示非正规HEX文件&#xff0c;不给我下载&#xff0c;郁闷了。 其实也简单&#xff0c;如下图所示配置文件后面加几行字就OK了。 //Output File -Ointel-extended,(XDATA).eep -Ointel-e…

【Qt】重新认识QObject

1、QObject父子对象的是设计模式中组合模式的实现。父对象和基对象不是一个概念&#xff0c;前者是在运行时管理子对象&#xff0c;是动态的&#xff0c;后者是在编译时判定派生关系&#xff0c;是静态的。 2、每个QObject至多有一个父对象&#xff0c;父对象中将子对象的指针放…

抛弃VS Code,我还能用啥编辑器?| 技术头条

作者 | Abhishek Prakash译者 | 苏本如责编 | 屠敏转载自 CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;微软的VS Code无论对Web开发人员或其他程序员来说&#xff0c;都是一款优秀的代码编辑器。凭借其出色的功能&#xff0c;VS Code被认为是最好的开源代码编辑器之一。…

WebClient UI和Tomcat的启动器

WebClient UI 我们在WebClient UI的开发工具里点了Test按钮&#xff0c; 会在浏览器以测试模式打开选中的view。这背后发生了什么事&#xff1f;注意浏览器地址栏的bspwd_cmp_test&#xff0c;这是什么东西&#xff1f;Jerry倾向于把它当作是CRM WebClient UI component在测试模…

通过网络安装VMware ESX Server 5

VMware ESX Server的宿主系统是基于Linux定制开发的&#xff0c;所以&#xff0c;它也和所有的Linux系统一样&#xff0c;除了支持光盘引导安装外&#xff0c;还支持基于PXE的网络引导与安装。在VMware ESX Server 4及其以前的版本中&#xff0c;在通过网络远程安装的时候&…

实战:CNN+BLSTM+CTC的验证码识别从训练到部署 | 技术头条

作者|_Coriander转载自Jerry的算法和NLP&#xff08;ID: gh_36eba310d433&#xff09;1.前言本项目适用于Python3.6&#xff0c;GPU>NVIDIA GTX1050Ti&#xff0c;原master分支已经正式切换为CNNLSTMCTC的版本了&#xff0c;是时候写一篇新的文章了。长话短说&#xff0c;开…

MySql练习题参考答案

表结构&#xff1a; /*Navicat Premium Data TransferSource Server : localhostSource Server Type : MySQLSource Server Version : 50624Source Host : localhostSource Database : sqlexamTarget Server Type : MySQLTarget Server Version …

【Qt】Qt源码中涉及到的设计模式

1、单例模式 qApp宏返回指向QApplication的单例 #define qApp (static_cast<QApplication *>(QCoreApplication::instance()))2、MVC模型视图控制器框架 模型是应用程序对象、视图是它的屏幕显示、控制器定义了用户界面对用户输入的反应。 Qt的模型视图框架是经典的MV…

从当前日期算起,获取几天前的日期和几个月前的日期

/*** 从当前日期算起&#xff0c;获取N天前的日期&#xff08;当前日不算在内&#xff09;&#xff0c;日期格式为yyyy-MM-dd* * param daily 天数* return */public static String getDateByDay(Integer daily) {Date date new Date();int year Integer.parseInt(new Simple…

清华大学人工智能研究院成立听觉智能研究中心,将专注基础研究和成果产业化

4月22日&#xff0c;清华大学人工智能研究院听觉智能研究中心&#xff08;以下简称听觉中心&#xff09;成立仪式暨学术前沿报告会在清华大学FIT楼举行。 清华大学副校长、人工智能研究院管委会主任尤政院士在致辞中表示&#xff0c;成立听觉中心是清华大学加速推进人工智能发…

两道面试题,带你解析Java类加载机制

2019独角兽企业重金招聘Python工程师标准>>> 在许多Java面试中&#xff0c;我们经常会看到关于Java类加载机制的考察&#xff0c;例如下面这道题&#xff1a; class Grandpa {static{System.out.println("爷爷在静态代码块");} } class Father extend…

【Qt】监视文件和目录的修改:QFileSystemWatcher

一、说明 QFileSystemWatcher用于监视指定文件或目录列表的更改。 注意:监视文件或目录时需要打开相应的文件描述符,因此被监视的文件或目录数据是有限的,受系统允许的文件描述符数据等限制。 二、常用成员函数 1、public 构造、析构函数: QFileSystemWatcher(const QS…

asp.net 2.0中新增的AppendDataBoundItems .dropdownlist 添加第一项

在asp.net 2.0中&#xff0c;新增了一个AppendDataBoundItems属性&#xff0c;十分方便&#xff0c;使可以在执行数据绑定之前将项添加到 listcontrol 对象中。执行数据绑定之后&#xff0c;项集合中包含数据源中的项以及以前添加的项。如果不在绑定数据之前清除列表项&#xf…

用Python实现OpenCV特征提取与图像检索 | Demo

参加「CTA 核心技术及应用峰会」&#xff0c;请扫码报名 ↑↑↑作者&#xff5c;Andrey Nikishaev翻译 | 张蔚敏审校 | reason_W来源 | Python大本营&#xff08;id&#xff1a;pythonnews)“拍立淘”“一键识花”“街景匹配”……不知道大家在使用这些神奇的功能的时候&#x…

【ffmpeg】编译时报错:error: undefined reference to `av...

1、问题描述 昨天使用ffmpeg库编译demo一切正常,今天再次链接ffmpeg库时报了一堆错误: error: undefined reference to `av_frame_alloc() error: undefined reference to `avio_close(AVIOContext*) error: undefined reference to `avcodec_find_encoder(AVCodecID) erro…

Spring Initializr 构建Spring Boot/Cloud工程

2019独角兽企业重金招聘Python工程师标准>>> 在之前的所有Spring Boot和Spring Cloud相关博文中&#xff0c;都会涉及Spring Boot工程的创建。而创建的方式多种多样&#xff0c;我们可以通过Maven来手工构建或是通过脚手架等方式快速搭建&#xff0c;也可以通过《Sp…

linux下用phpize给PHP动态添加扩展

使用php的常见问题是&#xff1a;编译php时忘记添加某扩展&#xff0c;后来想添加扩展&#xff0c;但是因为安装php后又装了一些东西如PEAR等&#xff0c;不想删除目录重装&#xff0c;别说&#xff0c;php还真有这样的功能。 我没有在手册中看到。 如我想增加bcmath支持&…

“996 是福利,007 才是常态”?!千万程序员怒怼每日优鲜!

呔&#xff01;热度不是你想蹭&#xff0c;想蹭就能蹭……作者 | 仲培艺封图 | CSDN 付费下载自东方IC出品 | 程序人生&#xff08;ID&#xff1a;coder_life&#xff09;App Store 评分一日之间从 4.5 断崖直降至 1.5&#xff0c;每日优鲜这是怎么了&#xff1f;究其原因——大…

亚太信息安全领袖成就表彰计划:阿里成中国互联网公司唯一代表

近日&#xff0c;全球最大的信息安全非营利会员组织(ISC)公布了第十二届年度亚太区信息安全领袖成就&#xff08;亚太区ISLA&#xff09;表彰计划的获奖者&#xff0c;共有17名人员获得此项殊荣。据悉&#xff0c;(ISC)将于2018年7月9日在香港举行的庆典活动中表彰这17名获奖者…

【C++】clipp 一个命令行参数解析器

1、简介 clipp是一个使用方便、功能强大的命令行解析器&#xff0c;源码只有一个头文件《clipp.h》 github地址&#xff1a;https://github.com/muellan/clipp 2、使用 只演示最简单的例子&#xff0c;更复杂的参见源码中《README.md》。 例如需要如下命令行参数 用法&…

Oracle 聚合函数(Aggregate Functions)说明

Oracle Aggregate Functions用过很多&#xff0c;官网的说明如下&#xff1a;Aggregate Functionshttp://docs.oracle.com/cd/E11882_01/server.112/e26088/functions003.htm#SQLRF20035Aggregatefunctions return a single result row based on groups of rows, rather than o…

【OpenCV】正确创建用于保存YUV420P格式的cv::Mat

1、问题描述 cv::Mat保存RGB24或BRG24格式时&#xff0c;传入宽、高和格式类型CV_8UC3就行了&#xff1b;今天在创建cv::Mat用来保存YUV420P时&#xff0c;有点懵圈了&#xff0c;因为类型是CV_8UC1&#xff0c;直接传宽和高&#xff0c;只能保存Y分量。因此需要宽或者高乘以一…

特斯拉全新自动驾驶芯片最强?英伟达回怼,投资者用脚投票

整理 | 一一出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;马斯克前脚刚说完自家发布的自动驾驶计算机是全球最强&#xff0c;后脚就被英伟达怼了。在刚刚结束的自动驾驶投资者日上&#xff0c;特斯拉发布了全自动驾驶&#xff08;FSD&#xff09;计算机&#xff08…

2012年我的十大工程9——形象工程

形象对于每一个人来说都很重要&#xff0c;人以群分&#xff0c;物以类聚&#xff01;说的就是这个道理&#xff0c;不同的人接触不同的社会&#xff0c;不同的级别接触不同的层面。还记得我【千日计划】项目中怎么说的吗&#xff1f;第七项&#xff1a;改良自己的外貌形象。老…

【MySQL】ubuntu16.04安装mysql,然后源码编译Qt5.12.4版本的libqsqlmysql.so

一、Ubuntu16.04.5 安装 MySQL 1、使用apt命令安装 sudo apt install mysql-server安装过程会提示,推荐设置MySQL的root用户密码(注意:这里root不是指ubuntu系统的root) While not mandatory, it is highly recommended that you set a password for the MySQL administr…

A* 算法之父、人工智能先驱Nils Nilsson逝世 | 缅怀

整理 | 琥珀出品 | AI科技大本营&#xff08;id&#xff1a;rgznai100&#xff09;2019 年 4 月 23 日&#xff0c;人工智能学科创始研究者之一、斯坦福大学计算机科学系 Kumagai 教授 Nils J. Nilsson 逝世&#xff0c;享年 86 岁。Nils J. Nilsson&#xff08;1933 年 2 月 6…

类执行方法的过程与运行时

大家都知道&#xff0c;调用一个未声明方法大多数情况下会崩溃&#xff0c;崩溃信息就是unrecognized selector sent to instance&#xff1b;是的&#xff0c;的确大多数情况下是这样的&#xff0c;但是有了运行时就不一定了&#xff0c;这就是我今天的主题——“安全类”(哈哈…

NandFlash系列之一:NorFlash与NandFlash对比

NandFlash系列之一&#xff1a;NorFlash与NandFlash对比作者&#xff1a;刘洪涛&#xff0c;华清远见嵌入式学院高级讲师。FLASH存储器又称闪存&#xff0c;主要有两种&#xff1a;NorFlash和NandFlash&#xff0c;下面我们从多个角度来对比介绍一下。在实际开发中&#xff0c;…

机器学习萌新必备的三种优化算法 | 选型指南

作者 | Nasir Hemed编译 | Rachel出品 | AI科技大本营&#xff08;id&#xff1a;rgznai100&#xff09;【导读】在本文中&#xff0c;作者对常用的三种机器学习优化算法&#xff08;牛顿法、梯度下降法、最速下降法&#xff09;进行了介绍和比较&#xff0c;并结合算法的数学原…