前言Node作为前后端分离的“利器”。因为它利用了JS语法的特殊性,可以让前端更好的使用Node作为中间层。调用后台提供的“黑盒子”API非常方便。即便以Node作为主服务器进行开发,项目中也会经常使用到其他系统调用服务的场景。请求认证一直是Web系统中非常重要的一环,直接关系到系统的安全性。对于服务端的Node来说,passport模块是使用最多的认证机制,稍微有点复杂。通过其强大灵活的Strategy机制,官方还提供了很多策略来满足很多常见的场景。当然,今天的话题是最简单的基础认证HTTPBasicAuthentication,它提供了http最基本的认证策略,即用户名和密码。在服务端调用API的场景中加入这个基础认证会比直接在前端使用这个比较“空”的更合适。本文将介绍在服务端使用Node调用API时如何处理最基本的HTTP认证——HTTPBasicAuthentication认证。即axios、request、restler等不同服务端http客户端的使用。HTTPBasicAuthentication首先简单介绍一下HTTPBasicAuthentication,最简单的http认证形式。如上图所示,当客户端进行资源请求时,由于接口API设置了http基本认证限制对资源的访问,客户端只有在客户端提供用户名和密码时才会获取到资源,并且服务器认证通过。实现下面将使用express构建一个需要基本身份验证的简单接口。需要注意的是,express在express3中也集成了丰富的中间件体系。例如,你可以直接通过app.use(express.basicAuth('username','password'));设置基本身份验证。由于express4开始分离中间件体系,需要多一步手动安装basic-auth中间件。//app.jsconstexpress=require('express')constbasicAuth=require('basic-auth')constbodyParser=require('body-parser')constapp=express();app.use(bodyParser.json())app.use(bodyParser.urlencoded({extended:true}))app.all('/api',function(req,res){constcredentials=basicAuth(req)if(!credentials||credentials.name!=='ray'||credentials.pass!=='123'){res.statusCode=401res.setHeader('WWW-Authenticate','Basicrealm="example"')res.end('goaway')}else{console.log(req.body)if(req.body.need&&req.body.need==='money'){res.json({key:'给我钱'});}else{res.json({key:'showmethegold'})}}});app.listen(3000,function(){console.log('示例应用监听端口3000!');});首先简单搭建一个提供api的服务器。执行nodeapp.js后访问localhost:3000/api时,会看到浏览器弹窗让在输入用户名和密码的对话框中,如果点击取消,即不提供用户名和密码,或者密码错误,都会验证失败,会看到'goaway'当您提供正确的密码时,您将获得“给我看黄金”。值得一提的是,在express的构建中,我使用了中间件body-parser。原因是我们在服务端使用node请求API时,会使用POST方式传递参数,也就是我要的是'showmethemoney'这句话。HTTPpost请求的默认数据格式是www-form-urlencoded,解析时需要bodyParser.urlencoded支持。在server端调用API其实有很多http客户端模块可以在Node端使用,比如可以使用pipe进行流式操作的request,还有我现在做的项目中使用的restler,当然还有现在很流行的前后端。都可以用,并且基于现代异步基础--Promise的axios,接下来就是引入这三个模块在服务端请求一个带有HTTPBasicAuthentication认证的API接口,简单的就是上面使用express构建的服务器得到短语“给我钱”。请求模块npminstall--saverequest将请求模块安装到我们的项目目录,然后创建一个新的req.js文件。//req.jsconstrequest=require('request')request.post('http://localhost:3000/api',{'auth':{'user':'ray','pass':'123','sendImmediately':false},'form':{need:'money'}},function(err,httpResponse,data){if(err){console.log(err);}else{console.log(`data:${data}`)}})request模块本身确实有点大。上面使用它的post方法,通过在第二个参数对象中写入auth属性,提供HTTP基本认证所需的用户名和密码。第二个属性form是放在请求body中的application/x-www-form-urlencoded参数,我们的expressserver会通过req.body来解析这个参数。当然需要bodyParser.urlencoded()来提供支持。接下来,先用nodeapp.js启动我们的服务器,然后你去nodereq.js运行这个文件,你会看到data:{"key":"yougetthemoney"}axiosmodulenpminstall--saveaxios,创建axi.js//axi.jsconstaxios=require('axios')axios({url:'http://localhost:3000/api',method:'post',auth:{username:'ray',密码:'123'},数据:{需要:'money'}}).then((response)=>{console.log(response.data)}).catch(function(error){console.log(错误);});axios最大的特点就是可以非常愉快的使用Promise,而且它的体积足够小。它的基本认证信息也在配置中的auth属性中,需要的放在body中,和request中的参数放在data字段中,需要注意的是他返回的数据在返回结果的数据字段。同样的,这时候你也可以在nodeaxi.js.restlermodulenpminstall--saverestler,newrest.jsconstrest=require('restler')rest中得到{key:'yougetthemoney'}。post('http://localhost:3000/api',{username:'ray',password:'123',data:{need:'money'}}).on('complete',function(data){console.log(data)})最后是restler模块,需要的认证信息直接在它的第二个参数options的两个字里sectionusername和password,body中携带的信息还是放在data字段中,使用监听complete事件的方法触发回调函数,得到验证后的消息{key:'你拿到钱了'}当然以上三个模块和浏览器发送的没有认证信息的请求会得到401“goaway”,并且三个模块会在请求体中没有参数需要的情况下“showyouthegold”。后续到此结束,如有错误和不足,还望大家指出:)完整的demo地址个人博客地址
