安全性
在无状态请求时访问api接口,服务器无法判断访问者。于是呢,我们就需要有一个用户认证,一般有两种方法:
session+cookie验证
token验证(包含部分信息的加密字符串)
1.用户登录 获取token (服务器) 保存token
2. 用户请求其他接口并且携带token
3. 服务器端 验证token 是否存在 token有效 验证ok 用户状态ok
token由三部分组成:
jsonwebtoken官网:https://jwt.io
header头文件信息、 payload 荷载、signature加密验证

讯享网
如何产生和验证token
1.下载第三方插件
npm install jsonwebtoken --save
讯享网
2.引入
讯享网const jwt=require('jsonwebtoken');
3.产生和验证token
(1)对称加密(私钥加密,私钥解密)
let payload={
//设置用户名为wangyi name:"wangyi" } //设置一个密钥 let secret="hahahheihei_wa" let token=jwt.sign(payload,secret) console.log(token)
打印的结果如下:

将打印的token粘贴到jwt官网的token位置,从图片中可以看出验证成功,荷载的参数信息也发生了改变,变成了我们自己定义的

用代码验证token是否合法:
讯享网let token='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoid2FuZ3lpIiwiaWF0IjoxNTQ0MDIxMjIwfQ.EhJzFHDKBaSfeFBebky9V1Np_PJCYsIm8XOp0vMKims' //第一个参数是token值,第二个参数是设置的密钥 let decoded=jwt.verify(token,'hahahheihei_wa'); console.log(decoded)
验证结果打印如下:

(2)非对称加密(私钥加密,公钥解密)-------私钥自己产生,公钥由私钥产生
- windows系统需要下载安装 OpenSSL
- 输入指令产生私钥:

openssl genrsa -out private_key.pem 1024 //genrsa非对称加密 -out输出路径 private_key.pem私钥的名字 1024 代表私钥长度
- 输入指令产生公钥
讯享网openssl rsa -in private_key.pem -pubout -out public_key.pem
- 产生token
//path需要引入 const path=require('path') var cert = fs.readFileSync(path.join(__dirname,'./private_key2.pem'));//产生的私钥的绝对路径 var token = jwt.sign(payload, cert, {
algorithm: 'RS256'});//荷载 私钥 加密方式 console.log(token)
- 验证token
讯享网let token='eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoid2FuZ3lpIiwiaWF0IjoxNTQzOTgxMTM1fQ.jvd1NfpyKtEYZT4RJ-phe_qWKUNEyBdO1ElhAqMcc1gCUxBV_we1s9KgY-o10MDs3MZUyd8p1M0RBObYBur-We9lunBV87mAK5bNzhPA8ezieZwpOpbSNnWHpF6IZa-lyDf4lG61MVpygQJEWA0pq0bllXZiQUOnSCnjU1RamZQ' var cert = fs.readFileSync(path.join(__dirname,'./public_key.pem'));//公钥的绝对路径 let result=jwt.verify(token, cert); console.log(result)
密码加密
- 哈希加密
- 盐加密=哈希+随机盐(复杂度更高,安全性就更高)
下载安装第三方模块bcrypt
npm install bcrypt --save
引入
讯享网const bcrypt = require('bcrypt');
代码实现
const bcrypt = require('bcrypt'); const saltRounds=10;//获取盐的参数,参数越大,加密的复杂度越大 const pass="sdasdsa12321";//设置一个密码 bcrypt.genSalt(saltRounds, function(err, salt) {
// 获取盐 console.time('test') bcrypt.hash(pass,salt,function(err,hash){
//获取哈希 console.log(hash) let result= bcrypt.compareSync('sdasdsa12321', hash);// 第一个参数:要比较的密码 第二个参数:加密后的密码 console.log(result) console.timeEnd('test') }) })
最后加密的结果及加密所耗时间

关于下载第三方模块 bcrypt
需要和node版本相对应(版本过高或过低都会报错)

下面我们来做一个注册登录吧
(此处我们用到了mvc框架)
- Model(模型)是应用程序中用于处理应用程序数据逻辑的部分
- View(视图)是应用程序中处理数据显示的部分。
- Controller(控制器)是应用程序中处理用户交互的部分。
Model部分:
讯享网const express=require('express'); const jwt = require('jsonwebtoken') const router=express.Router(); const adminUserCtr=require("../controller/adminUser.controller.js") router.post('/reg',adminUserCtr.reg) router.post('/login',adminUserCtr.login) module.exports=router
Controller部分:
const bcrypt=require('bcrypt'); const tools=require('../tools/tools.js') const User=require('../db/model/adminUserModel.js') let reg=(req,res)=>{
//获取数据 let{
adminName,passWord}=req.body; User.find({
adminName}) .then((data)=>{
if(data.length>=1){
throw '用户已存在' }else{
//进行插入数据库操作 //插入之前进行密码加密,通过盐+哈希的方法 var salt = bcrypt.genSaltSync(10)//产生盐 var hash = bcrypt.hashSync(passWord,salt) return User.insertMany({
adminName:adminName,passWord:hash}) } }) .then((data)=>{
res.send({
err:0,msg:'注册ok'}) }) .catch((error)=>{
res.send({
err:-1,msg:error}) }) } let login=(req,res)=>{
let{
adminName,passWord}=req.body; User.find({
adminName}) .then((data)=>{
console.log(data) if(!data.length){
throw '用户名不存在' } //用户名存在 //密码在数组里面的第一个对象里,key键为passWord let hash=data[0]['passWord']; let result=bcrypt.compareSync(passWord, hash); if(!result){
throw "用户名或密码错误" } //产生token let token=tools.createToken(adminName) res.send({
err:0,msg:'恭喜您登陆成功',token:token}) }) .catch((error)=>{
res.send({
err:-1,msg:error}) }) } module.exports={
reg, login }
讯享网<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <meta name="renderer" content="webkit|ie-comp|ie-stand"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" /> <meta http-equiv="Cache-Control" content="no-siteapp" /> <!--[if lt IE 9]> <script type="text/javascript" src="lib/html5.js"></script> <script type="text/javascript" src="lib/respond.min.js"></script> <![endif]--> <link href="static/h-ui/css/H-ui.min.css" rel="stylesheet" type="text/css" /> <link href="static/h-ui.admin/css/style.css" rel="stylesheet" type="text/css" /> <link href="lib/Hui-iconfont/1.0.8/iconfont.css" rel="stylesheet" type="text/css" /> <!--[if IE 6]> <script type="text/javascript" src="http://lib.h-ui.net/DD_belatedPNG_0.0.8a-min.js" ></script> <script>DD_belatedPNG.fix('*');</script><![endif]--> <title>后台登录</title> <style> .loginWraper{
margin: 100px auto; } .input-text{
width: 500px } </style> </head> <body> <input type="hidden" id="TenantId" name="TenantId" value="" /> <div class="header"></div> <div class="loginWraper"> <div id="loginform" class="loginBox"> <div class="form form-horizontal"> <div class="row cl"> <label class="form-label col-xs-3"><i class="Hui-iconfont"></i></label> <div class="formControls col-xs-8"> <input name="adminName" type="text" placeholder="账户" class="input-text size-L "> </div> </div> <div class="row cl"> <label class="form-label col-xs-3"><i class="Hui-iconfont"></i></label> <div class="formControls col-xs-8"> <input name="passWord" type="password" placeholder="密码" class="input-text size-L "> </div> </div> <div class="row cl"> <div class="formControls col-xs-8 col-xs-offset-3"> <label for="online"> <input type="checkbox" name="online" id="online" value=""> 使我保持登录状态</label> </div> </div> <div class="row cl"> <div class="formControls col-xs-8 col-xs-offset-3"> <input onclick="login()" name="" type="submit" class="btn btn-success radius size-L" value=" 登 录 "> <input name="" type="reset" class="btn btn-default radius size-L" value=" 取 消 "> </div> </div> </div> </div> </div> <div class="footer">Copyright 某某有限公司 by H-ui.admin.page.v3.0</div> <script type="text/javascript" src="lib/jquery/1.9.1/jquery.min.js"></script> <script type="text/javascript" src="static/h-ui/js/H-ui.js"></script> <script> function login(){
var adminName=$("input[name='adminName']").val(); let localstorage=window.localStorage //传值 localstorage.setItem("adminName",adminName); // console.log(localstorage.getItem("adminName")); var passWord=$("input[name='passWord']").val(); $.post( "http://127.0.0.1/admin/adminUser/login", {
adminName:`${
adminName}`,passWord:`${
passWord}`}, function(res){
console.log(res) if(res.err==0){
location.href='http://127.0.0.1/page/picture-list.html' }else{
alert(res.msg) } }) } </script> </body> </html>




版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/125998.html