随身笔记
随身笔记

node.js实现token身份验证

node token node.js node

《token理解、学习》

 

安装必要模块:

//koa-jwt 中间件,使用后为每个路由添加校验方法,就不需要一个个手动添加
npm install -S koa-jwt


//生成token
npm install -S jsonwebtoken@9.0.0   //对应node版本v12.20.2至少要》12

 

 

1,假设用户使用正确的帐号和密码登录,后台就会生成一个token,返回给浏览器,并保存在浏览器本地中,下次要进入后台就需要从本地获取到token传给后台

const jwt = require('jsonwebtoken');
//生成token

router.get('/',async (ctx, next) => { //这里模拟,用户输入对的帐号密码时就会执行以下逻辑
    const token = jwt.sign({
       name: 123
    },'user_pass_xxx' //随便一点内容,撒盐:加密的时候混淆
    ,{
     expiresIn: 60 //60秒到期时间
    });

   //把token存放在本地
   ctx.cookies.set(
     'state',
      token,
      {
           domain: 'localhost', // 写cookie所在的域名
           path: '/', // 写cookie所在的路径
           maxAge: 10 * 60 * 1000, // cookie有效时长
           expires: new Date('2019-07-15'), // cookie失效时间
           httpOnly: false, // 是否只用于http请求中获取
           overwrite: false // 是否允许重写
      }
    )
    ctx.body='成功'
})

 

生成的token内容类似于:(以下代码是JWT数据格式,具体可以参考地址)

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoxMjMsImlhdCI6MTQ5MTQ3NTQyNCwiZXhwIjoxNDkxNDc1NDg0fQ.hYNC4qFAyhZClmPaLixfN137d41R2CFk1xPlfLK10JU

 

//解密token
jwt.verify(token, 'user_pass_xxx', function (err, decoded) {
  if (!err){
     console.log(decoded.name); //会输出123,如果过了60秒,则有错误。
  }
})

 

 

2,把token用cookies存储在本地里,每次请求需要用帐号和密码校验对了才能显示的页面时,就必须把token从cookies里提取出来把token值带入到request headers,之后服务器才能获取到token值。

使用ajax把token值传入到request headers后在带给后台

 

 

3,服务器获取到客服端从request headers带入的token值后,就可以进行逻辑判断了,如果有token值并没过期就显示出相应的页面或数据

 

const app = new Koa()
const koajwt = require('koa-jwt')

app.use(async (ctx,next)=>{  //必须在koajwt验证之前把token传给服务器,不然根本访问不了路由
    console.log('app.js里面'+ctx.cookies.get('state'));
    ctx.request.header = {'authorization': "Bearer " + ctx.cookies.get('state')}
    await next();
});
app.use(koajwt({secret: 'user_pass_xxx'}).unless({path:[/^\/api\/login/, /^\/api\/register/]})) //usless排除进行jwt校验的路由
                                        //unless({ path: ['/public']}) ,每个路由都要校验token除了,访问/public路由时不需要


//在路由中处理
const router = require('koa-router')()
router.post('/xxx', async ctx => {
  const token = ctx.state.user //从request headers带入token值,才能使用这种方法获取
  console.log(token.id)
  console.log(token.secret)
}




 

//单独为某个路由添加校验

get('/helloworld', koajwt({
 secret: 'user_pass_xxx', // Should not be hardcoded
}), async(ctx) => {
 ctx.body = 'helloworld page!' //通过了token才能显示内容
})

 

 

完成代码:

编辑app.js

const koajwt = require("koa-jwt");

// 自定义接口错误信息
app.use(async (ctx, next) => {
    return next().catch(err => {
        if (err.status === 401) {
            // 自定义返回结果
            ctx.status = 200;
            console.log(err.name);
            ctx.body = {
                code: 401,
                msg: '登录超时'//err.message
            };
        } else {
            throw err;
        }
    });
});


//以后每请求接口都会去拿cookie里面的token是否正常接口才能请求的通
app.use(
    koajwt({
        secret:'user_pass_xxx',
        cookie: 'token', // 从 cookie 中获取token,cookie字段名是token
        debug: false // 开启debug可以看到准确的错误信息
    })
        .unless({ path:[/^\/login/, /^\/logout/, /^\/code_img/] })
);





// routes
app.use(index.routes(), index.allowedMethods())
app.use(users.routes(), users.allowedMethods())

 

编辑路由的登录接口

const jwt = require('jsonwebtoken');


router.post('/login',async (ctx,next)=>{

   var obj = await new Promise((a,b)=>{
        db.get('username').find({"user":"admin"}).then((doc)=>{

            var pass = en_pass((ctx.request.body.password))

            if(doc[0].user===ctx.request.body.username && doc[0].pass===pass){ //客户端输入的账号密码和数据库匹配

                //----------------生成token-----------------------------------
                const token = jwt.sign({
                        "username":ctx.request.body.username,
                        "pass":pass
                    },'user_pass_xxx' //随便一点内容,撒盐:加密的时候混淆
                    ,{
                        expiresIn: 60 * 60 * 24 //token24小时后过期
                    });
                //----------------生成token-----------------------------------
                
                   a(token);

            }else{
                a(false);
            }

        });
    })

    ctx.body={
        code:obj?200:401,
        data:obj?obj:null,
        msg:obj?'登录成功':'密码错误'
    }

})

只要登录成功,就要让后端或者前端去生成cookie,且字段名为token值是jwt.sign()生成的,以后每请求接口都会效验token是否正常接口才能请求的通

 

 

参考文章有:

https://www.dengxiangxing.com/post/42072

http://yunzaifei.github.io/2017/09/22/koa2%E5%BC%80%E5%8F%91%E7%9A%84api%E6%9C%8D%E5%8A%A1%E5%8F%8Ajwt%E5%BA%94%E7%94%A8/

https://www.jianshu.com/p/a7882080c541

https://segmentfault.com/a/1190000009494020

https://www.npmjs.com/package/jsonwebtoken

 

 

随身笔记

node.js实现token身份验证
node token node.js node 《token理解、学习》   安装必要模块: //koa-jwt 中间件,使用后为每个路由添加校验方法,就不需要一个个手动添加 npm install -S koa-jwt …
扫描二维码继续阅读
2018-01-18