美文网首页
基于token的身份验证

基于token的身份验证

作者: nzjcnjzx | 来源:发表于2019-06-04 17:19 被阅读0次

传统基于服务器的验证方式

传统的验证方式是基于服务器的,就是把登陆信息存在服务端,每次登陆需要去辨别存储的登陆信息,一般都是通过session来实现, 这样会有一些问题,比如每次认证用户发起请求时,服务器都需要创建一个用记录来存储信息,当越来越多的用户发起请求时,内存的开销也会不断的增加

基于token的验证原理

基于token的身份验证是无状态的,我们不用将信息存储在服务器或者session中。token通过请求头传输,而不是把认证信息存储在服务器或者session中,就意味着可以从任意一种可以发送HTTP请求的终端向服务器发送请求

实现步骤

  1. 登陆时,客户端发送用户名密码
  2. 服务端验证用户名密码是否正确,校验通过就会生成一个有时效的token串,发送给客户端
  3. 客户端储存token,一般都会存储在localStorage或者cookie里面
  4. 客户端每次请求时都带有token,可以将其放在请求头里,每次请求都携带token
  5. 服务端验证token,所有需要校验身份的接口都会被校验token,若token解析后的数据包含用户身份信息,则身份验证通过,返回数据

node + jwt(jsonwebtoken) 搭建token身份验证

npm i jsonwebtoken  --save // 安装jsonwebtoken模块
// 引入模块依赖
const fs = require('fs');
const path = require('path');
const jwt = require('jsonwebtoken');
// 创建 token 类
class Jwt {
    constructor(data) {
        this.data = data;

    }

    //生成token
    generateToken() {
        let data = this.data;
        let created = Math.floor(Date.now() / 1000);
        let cert = fs.readFileSync(path.join(__dirname, '../pem/private_key.pem'));//私钥 可以自己生成
        let token = jwt.sign({
            data,
            exp: created + 60 * 30,
        }, cert, {algorithm: 'RS256'});
        return token;
    }

    // 校验token
    verifyToken() {
        let token = this.data;
        let cert = fs.readFileSync(path.join(__dirname, '../pem/public_key.pem'));//公钥 可以自己生成
        let res;
        try {
            let result = jwt.verify(token, cert, {algorithms: ['RS256']}) || {};
            let {exp = 0} = result, current = Math.floor(Date.now() / 1000);
            if (current <= exp) {
                res = result.data || {};
            }
        } catch (e) {
            res = 'err';
        }
        return res;
    }
}
module.exports = Jwt;

使用jwt token工具

/ 引入jwt token工具
const JwtUtil = require('../public/utils/jwt');
// 我这里的是aes加密密码的可以去掉
const AesUtil = require('../public/utils/aes');
// 登录
router.post('/login',(req,res) => {
    var userName = req.body.user;
    var pass = req.body.pass;
    new Promise((resolve, reject) => {
        // 根据用户名查询用户
        users.findOne({'username':userName}).exec((err,result) => {
           if(err){
               reject(err);
           }else{
               resolve(result);
           }
        });
    }).then((result) => {
        console.log(result);
        if(result){
            // 密码解密 利用aes
            var aes = new AesUtil(result.password);
            var password = aes.deCryto();
            if(pass == password){
                // 登陆成功,添加token验证
                let _id = result._id.toString();
                // 将用户id传入并生成token
                let jwt = new JwtUtil(_id);
                let token = jwt.generateToken();
                // 将 token 返回给客户端
                res.send({status:200,msg:'登陆成功',token:token});
            }else{
                res.send({status:400,msg:'账号密码错误'});
            }
        }else{
            res.send({status:404,msg:'账号不存在'})
        }
    }).catch((err) => {
        console.log(err);
        res.send({status:500,msg:'账号密码错误'});
    })
});

app.use(function (req, res, next) {
    // 我这里知识把登陆和注册请求去掉了,其他的多有请求都需要进行token校验 
    if (req.url != '/user/login' && req.url != '/user/register') {
        let token = req.headers.token;
        let jwt = new JwtUtil(token);
        let result = jwt.verifyToken();
        // 如果考验通过就next,否则就返回登陆信息不正确
        if (result == 'err') {
            console.log(result);
            res.send({status: 403, msg: '登录已过期,请重新登录'});
            // res.render('login.html');
        } else {
            next();
        }
    } else {
        next();
    }
});

前端请求封装

export default class FetchAsync {
    // get
    static getFatch(url) {
        let geturl = url;
        return new Promise((resolve, reject) => {
                var url = 'http://127.0.0.1:3001/' + geturl;
                fetch(url, {
                    method: 'GET',
                    header: {
                        'Accept': 'application/json',
                        'Content-Type': 'application/json',
                        'Token': localStorage.getItem('token')
                    },
                }).then((response) => {
                    if (response.ok) {
                        return response.json();
                    } else {
                        reject({status: response.status})
                    }
                }).then((res) => {
                    resolve(res)
                }).catch((err) => {
                    reject(err)
                })
            }
        )
    }

    // post
    static postFatch(url, params) {
        console.log(params);
        var url = 'http://127.0.0.1:3001/' + url;
        return new Promise((resolve, reject) => {
                fetch(url, {
                    method: 'POST',
                    headers: {
                        "Content-Type": "application/json;charset=utf-8",
                        'Token': localStorage.getItem('token')
                    },
                    body: JSON.stringify(params)
                }).then(response => response.json()).then((res) => {
                    resolve(res);
                }).catch((err) => {
                    reject(err)
                });
            }
        )
    }
}
公钥可以使用openssl通过命令来生成
  • window下生成命令
公钥生成  genrsa -out rsa_private_key.pem 1024
私钥生成  rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
  • mac下生成命令
私钥生成 openssl genrsa -out rsa_private_key.pem 1024
公钥生成 openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
使用node自带的加密模块crypto
const crypto = require('crypto')
function md5(content) {
  crypto.createHash('md5').update(content).digest('hex')
}

相关文章

  • Vue 后台管理项目5-登录状态判断(token令牌)

    登录状态判断(token令牌) 1.token令牌 Ⅰ.传统身份验证的方法: Ⅱ.基于 Token 的身份验证方法...

  • 基于 Token 的身份验证方法

    基于 Token 的身份验证方法 使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流...

  • Django JWT

    参考基于 Token 的身份验证、JSON Web Token - 在Web应用间安全地传递信息、基于cookie...

  • vue+axios+springmvc身份验证

    后台用的是基于Token 的身份验证——JWT(json web token) 1.maven 配置 在pom.x...

  • Cookie和Token

    前言 本文将首先概述基于cookie的身份验证方式和基于token的身份验证方式,在此基础上对两种验证进行比较。最...

  • 基于 Token 的身份验证

    基于 Token 的身份验证,很多大型网站也都在用,比如 Facebook,Twitter,Google+,Git...

  • 基于 Token 的身份验证

    最近了解下基于 Token 的身份验证,跟大伙分享下。很多大型网站也都在用,比如 Facebook,Twitter...

  • 基于 Token 的身份验证

    最近了解下基于 Token 的身份验证,跟大伙分享下。很多大型网站也都在用,比如Facebook,Twitter,...

  • 基于token的身份验证

    传统基于服务器的验证方式 传统的验证方式是基于服务器的,就是把登陆信息存在服务端,每次登陆需要去辨别存储的登陆信息...

  • 基于token的身份认证:JSON Web Token(附:No

    前言 在大多数的应用里,身份验证是必须的。最近学习了基于token的身份验证,很多大型网站也在用,例如Facebo...

网友评论

      本文标题:基于token的身份验证

      本文链接:https://www.haomeiwen.com/subject/lcdrxctx.html