博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Node.js的Koa实现JWT用户认证
阅读量:6040 次
发布时间:2019-06-20

本文共 3960 字,大约阅读时间需要 13 分钟。

版权声明

转载请告知并注明来源作者

作者唐金健
网络昵称御焱
专栏优雅的前端

一、前置知识

二、环境

  • Microsoft Visual Studio 2017集成开发环境
  • Node.js v8.9.4Javascript运行环境

三、开始动手,一步步来完善

1、创建基础的静态资源服务器、基础架构

  以下是基本的代码,实现静态服务器,以及一个当token验证异常时候的处理。

  下面我们将在这个基本代码下逐步增加注册、登录、信息的功能。

const path    = require('path');         // 用于处理目录路径const Koa     = require('koa');          // web开发框架const serve   = require('koa-static');   // 静态资源处理const route   = require('koa-route');    // 路由中间件const jwt     = require('jsonwebtoken'); // 用于签发、解析`token`const jwtKoa  = require('koa-jwt');      // 用于路由权限控制const koaBody = require('koa-body');     // 用于查询字符串解析到`ctx.request.query`const app     = new Koa();const website = {    scheme: 'http',    host: 'localhost',    port: 1337,    join: function () {        return `${
this.scheme}://${
this.host}:${
this.port}` }}/* jwt密钥 */const secret = 'secret';/* 当token验证异常时候的处理,如token过期、token错误 */app.use((ctx, next) => { return next().catch((err) => { if (err.status === 401) { ctx.status = 401; ctx.body = { ok: false, msg: err.originalError ? err.originalError.message : err.message } } else { throw err; } });});/* 查询字符串解析到`ctx.request.query` */app.use(koaBody());/* 路由权限控制 */// 待办事项……/* POST /api/register 注册 */// 待办事项……/* GET /api/login 登录 */// 待办事项……/* GET /api/info 信息 */// 待办事项……/* 静态资源处理 */app.use(serve(path.join(__dirname, 'static')));/* 监听服务器端口 */app.listen(website.port, () => { console.log(`${website.join()} 服务器已经启动!`);});复制代码

  下面,我们将在注册、登录、信息的注释底下添加实现的代码。

2、路由权限控制

  注册、登录接口、其它资源不需要认证,信息接口需要认证。

/* 路由权限控制 */app.use(jwtKoa({ secret: secret }).unless({    // 设置login、register接口,可以不需要认证访问    path: [        /^\/api\/login/,        /^\/api\/register/,        /^((?!\/api).)*$/   // 设置除了私有接口外的其它资源,可以不需要认证访问    ]}));复制代码

3、注册

/* POST /api/register 注册 */app.use(route.post('/api/register', async (ctx, next) => {    const body = ctx.request.body;    /*     * body = {     *  user : '御焱',     *  password : '123456'     * }     */    // 判断 body.user 和 body.password 格式是否正确    // 待办事项……    // 判断用户是否已经注册    // 待办事项……    // 保存到新用户到数据库中    // 待办事项……    // 是否注册成功    let 是否注册成功 = true;    if (是否注册成功) {        // 返回一个注册成功的JOSN数据给前端        return ctx.body = {            ok: true,            msg: '注册成功',            token: getToken({ user: body.user, password: body.password })        }    } else {        // 返回一个注册失败的JOSN数据给前端        return ctx.body = {            ok: false,            msg: '注册失败'        }    }}));/* 获取一个期限为4小时的token */function getToken(payload = {}) {    return jwt.sign(payload, secret, { expiresIn: '4h' });}复制代码

3、登录

/* GET /api/login 登录 */app.use(route.get('/api/login', async (ctx, next) => {    const query = ctx.request.query;    /*     * query = {     *  user : '御焱',     *  password : '123456'     * }     */    // 判断 query.user 和 query.password 格式是否正确    // 待办事项……    // 判断是否已经注册    // 待办事项……        // 判断姓名、学号是否正确    // 待办事项……        return ctx.body = {        ok: true,        msg: '登录成功',        token: getToken({ user: query.user, password: query.password })    }}));复制代码

  前端获取到token之后,可以保存在任意本地存储里。

4、信息

/* GET /api/info 信息 */app.use(route.get('/api/info', async (ctx, next) => {    // 前端访问时会附带token在请求头    payload = getJWTPayload(ctx.headers.authorization)    /*     * payload = {     * user : "御焱",     * iat : 1524042454,     * exp : 1524056854     * }     */    // 根据 payload.user 查询该用户在数据库中的信息    // 待办事项……    const info = {        name: '御焱',        age: 10,        sex: '男'    }    let 获取信息成功 = true;    if (获取信息成功) {        return ctx.body = {            ok: true,            msg: '获取信息成功',            data: info        }    } else {        return ctx.body = {            ok: false,            msg: '获取信息失败'        }    }}));/* 通过token获取JWT的payload部分 */function getJWTPayload(token) {    // 验证并解析JWT    return jwt.verify(token.split(' ')[1], secret);}复制代码

  访问需要认证的接口时,需要在
request头附带
Authorization:Bearer [token]字段。

你可能感兴趣的文章
【书单】book list
查看>>
内存泄漏和内存溢出
查看>>
道路运输车辆卫星定位系统标准符合性测试 ----操作方法和注意事项
查看>>
Objective-C中常用的结构体NSRange,NSPoint,NSSize(CGSize),NSRect
查看>>
关于spark standalone模式下的executor问题
查看>>
TC SRM 664 div2 B BearPlaysDiv2 bfs
查看>>
ABZ理论
查看>>
C#如何使用和开发自定义配置节
查看>>
hdu 1078 FatMouse and Cheese(记忆化搜索)
查看>>
Base64编码 概念和用途
查看>>
[CareerCup] 5.8 Draw Horizonatal Line 画横线
查看>>
css3 2D转换(2D Transform) 动画(Animation)
查看>>
算法导论 - 函数的增长。
查看>>
【大数据】Linux下安装Hadoop(2.7.1)详解及WordCount运行
查看>>
iOS开发之SQLite-C语言接口规范(一)——Ready And Open Your SQLite
查看>>
条件注释判断浏览器版本<!--[if lt IE 9]>
查看>>
iOS chart 图表完美解决方案 基于swift
查看>>
软件开发流程(转载)
查看>>
/usr/bin/cd 是什么鬼
查看>>
Linux 在下面MATLAB下载
查看>>