前言
Node作為前后端分離的”利器“由于它使用JS語法的特殊性撩银,可以使得前端更好的利用Node來作為中間層十分方便得調(diào)用后臺提供的“黑盒”API。即便是使用Node為主作為服務(wù)端開發(fā)在項目中也會經(jīng)常用到要去其他的系統(tǒng)調(diào)用服務(wù)的場景。
請求的認(rèn)證一直是一個web系統(tǒng)很重要的一環(huán),直接關(guān)系到了系統(tǒng)的安全碰逸。對于Node在服務(wù)端方面削祈,稍微復(fù)雜的認(rèn)證機(jī)制使用的最多的就是passport模塊饰抒,通過它強大而又靈活的Strategy機(jī)制肮砾,官方同時也提供了很多策略滿足很多常見的場景。當(dāng)然今天的主題是最簡單的基礎(chǔ)認(rèn)證 HTTP Basic Authentication袋坑,提供了對http最為基礎(chǔ)的認(rèn)證策略仗处,即用戶名和密碼。對于服務(wù)端調(diào)用API的場景加上這個基本認(rèn)證也會比在前端直接使用這種比較“空”的更加合適枣宫。
本文將介紹使用Node在服務(wù)端調(diào)用API時面對最基本的HTTP認(rèn)證 -- HTTP Basic Authentication認(rèn)證的處理方式婆誓。即不同的服務(wù)端http client
諸如axios, request, restler的使用。
HTTP Basic Authentication
首先對HTTP Basic Authentication這個最簡單的http認(rèn)證形式進(jìn)行簡單介紹
上圖所示也颤,在客戶端進(jìn)行資源請求的時候由于該接口API設(shè)置了http基本認(rèn)證對資源的訪問進(jìn)行了限制洋幻,則客戶端必須提供用戶名和密碼并且服務(wù)端驗證通過時才會得到資源。
實現(xiàn)
下面將使用使用express搭建一個簡單的需要基本認(rèn)證的接口翅娶,需要說明的是在express3中express還集成了很豐富的中間件系統(tǒng)鞋屈,比如你可以直接通過app.use(express.basicAuth('username', 'password'));
來設(shè)置一個基本認(rèn)證。在express4開始由于分離了中間件系統(tǒng),你需要多出一步手動安裝basic-auth中間件的過程故觅。
//app.js
const express = require('express')
const basicAuth = require('basic-auth')
const bodyParser = require('body-parser')
const app = express();
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended:true
}))
app.all('/api', function (req, res) {
const credentials = basicAuth(req)
if (!credentials || credentials.name !== 'ray' || credentials.pass !== '123') {
res.statusCode = 401
res.setHeader('WWW-Authenticate', 'Basic realm="example"')
res.end('go away')
} else {
console.log(req.body)
if(req.body.need && req.body.need === 'money'){
res.json({
key: 'show me the money'
});
}else{
res.json({
key: 'show me the gold'
})
}
}
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
先簡單的搭建起一個提供api的服務(wù)器厂庇,當(dāng)你執(zhí)行node app.js
之后訪問localhost:3000/api
的時候就會看到瀏覽器彈出讓你輸入用戶名和密碼的對話框,你如果點擊了取消输吏,即不提供用戶名和密碼权旷,或者錯誤密碼,就會驗證失敗贯溅,你將看到‘go away’拄氯。當(dāng)你提供了正確的密碼則將得到'show me the gold'。
值得一提的是它浅,express的搭建中,我使用了body-parser這個中間件译柏,原因是接下來我們使用node在服務(wù)端請求api的時候會使用POST方法傳遞參數(shù),即我想得到的是'show me the money'這句話姐霍。而http的post請求默認(rèn)的數(shù)據(jù)格式是www-form-urlencoded
解析的時候需要bodyParser.urlencoded
支持鄙麦。
在服務(wù)端調(diào)用API
其實在Node端可以用的http client
模塊有很多,比如可以使用pipe進(jìn)行流式操作的request,以及我現(xiàn)在在做的項目中使用的restler,當(dāng)然還有現(xiàn)在很火爆的前后端都可以使用镊折,并且基于現(xiàn)代異步基礎(chǔ)--Promise的axios,接下來就介紹對于這三個模塊在服務(wù)端去請求一個設(shè)了HTTP Basic Authentication認(rèn)證的API接口胯府,就是從我們上面用express搭起來的簡單的服務(wù)器得到'show me the money'
這句話。
request模塊
npm install --save request
安裝request模塊到我們項目目錄恨胚,然后新建req.js
文件骂因。
//req.js
const request = 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
方法赃泡,通過在第二個參數(shù)對象中寫上auth
屬性提供對http基礎(chǔ)認(rèn)證所需要的用戶名和密碼寒波,第二個屬性form
就是放在請求的body中的類型為application/x-www-form-urlencoded
參數(shù)乘盼,將會被我們的express服務(wù)器通過req.body
解析到,當(dāng)然俄烁,需要bodyParser.urlencoded()
提供支持蹦肴。
接下來,先node app.js
開啟我們的服務(wù)器猴娩,之后你再去node req.js
運行這個文件你就會看到data:{"key":"you get the money"}
了
axios模塊
npm install --save axios
,新建axi.js
//axi.js
const axios = require('axios')
axios({
url: 'http://localhost:3000/api',
method: 'post',
auth: {
username: 'ray',
password: '123'
},
data: {
need: 'money'
}
})
.then((response) => {
console.log(response.data)
})
.catch(function (error) {
console.log(error);
});
axios
最大的特點就是可以十分愉快的使用Promise,并且它的體積足夠的小勺阐,它對基礎(chǔ)認(rèn)證的信息同樣也是在配置中的auth
屬性卷中,而他所需要隨請求放在body中的參數(shù)是放在data
字段中,而且需要注意的是他返回的數(shù)據(jù)是在返回結(jié)果的data
字段中渊抽,同樣蟆豫,此時你node axi.js
也能得到{ key: 'you get the money' }
.
restler模塊
npm install --save restler
,新建rest.js
const rest = require('restler')
rest.post('http://localhost:3000/api',{
username:'ray',
password:'123',
data: {
need:'money'
}
}).on('complete',function(data){
console.log(data)
})
最后是restler
模塊,需要的認(rèn)證信息直接是其第二個參數(shù)options中的兩個字段username
和password
,攜帶在body中的信息依舊是放在data
字段中,用監(jiān)聽事件的方式監(jiān)聽complete
事件發(fā)生觸發(fā)回調(diào)函數(shù)你就得到了通過驗證的消息{ key: 'you get the money' }
懒闷。
當(dāng)然上述三個模塊以及瀏覽器發(fā)送請求不帶認(rèn)證信息都將得到帶著401的"go away",三個模塊不在請求的body中帶上參數(shù)need
都會”show you the gold”十减。