最近Nodejs,python越来越火了,同时也越来越多的人在用node写服务,可是怎么去调试服务呢?以及当你一个服务发布出去,怎么保证其安全性呢?

环境:linux unbuntu

语言:nodejs

工具:npm,mongodb,HttpIE

昨天写API的时候遇到了一个苦恼,就是我怎么去调试一个Api,当然有人会说客户端调用一下,然后debug模式就可以跟踪了,可是我昨天没有客户端,怎么办呢?后来找到了一个非常好的工具HttpIE,怎么安装可以参考 https://httpie.org/doc#linux,大家可能根据自己的开发环境去安装

example:

# Debian, Ubuntu, etc.

apt-get install httpie

# Fedora, CentOS, RHEL, …

yum install httpie

# Arch Linux

pacman -S httpie

不过万事都有不顺的时候,我在安装的时候遇到了一个问题

william@ubuntu:~$ sudo apt-get install httpie
[sudo] password for william:
Reading package lists... Done
Building dependency tree
Reading state information... Done
You might want to run 'apt-get -f install' to correct these:
The following packages have unmet dependencies:
cpp-5 : Depends: gcc-5-base (= 5.4.0-6ubuntu1~16.04.2) but 5.4.0-6ubuntu1~16.04.4 is to be installed
gcc-5 : Depends: cpp-5 (= 5.4.0-6ubuntu1~16.04.4) but 5.4.0-6ubuntu1~16.04.2 is to be installed
google-chrome-stable : Depends: libappindicator1 but it is not going to be installed
httpie : Depends: python-pygments but it is not going to be installed
Depends: python-requests but it is not going to be installed
libstdc++-5-dev : Depends: libstdc++6 (>= 5.4.0-6ubuntu1~16.04.4) but 5.4.0-6ubuntu1~16.04.2 is to be installed
libstdc++6 : Depends: gcc-5-base (= 5.4.0-6ubuntu1~16.04.2) but 5.4.0-6ubuntu1~16.04.4 is to be installed
E: Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).
william@ubuntu:~$ sudo apt-get -f install
Reading package lists... Done
Building dependency tree
Reading state information... Done
Correcting dependencies... Done
The following additional packages will be installed:
cpp-5 libappindicator1 libindicator7 libstdc++6
Suggested packages:
gcc-5-locales
The following NEW packages will be installed:
libappindicator1 libindicator7
The following packages will be upgraded:
cpp-5 libstdc++6
2 upgraded, 2 newly installed, 0 to remove and 441 not upgraded.
17 not fully installed or removed.
Need to get 0 B/8,088 kB of archives.
After this operation, 161 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
(Reading database ... 214296 files and directories currently installed.)
Preparing to unpack .../cpp-5_5.4.0-6ubuntu1~16.04.4_amd64.deb ...
Unpacking cpp-5 (5.4.0-6ubuntu1~16.04.4) over (5.4.0-6ubuntu1~16.04.2) ...
dpkg-deb (subprocess): decompressing archive member: lzma error: compressed data is corrupt
dpkg-deb: error: subprocess <decompress> returned error exit status 2
dpkg: error processing archive /var/cache/apt/archives/cpp-5_5.4.0-6ubuntu1~16.04.4_amd64.deb (--unpack):
cannot copy extracted data for './usr/lib/gcc/x86_64-linux-gnu/5/cc1' to '/usr/lib/gcc/x86_64-linux-gnu/5/cc1.dpkg-new': unexpected end of file or stream
Errors were encountered while processing:
/var/cache/apt/archives/cpp-5_5.4.0-6ubuntu1~16.04.4_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

 报错了,原因是需要清除掉缓存

william@ubuntu:~$ sudo apt-get clean

然后重复上面的操作(蓝色字体)的命令就可以完成了

怎么用HttpIE去调试API呢,比如我需要调试添加一条article记录怎么办呢? http://localhost:1337/api/articles,

$ http POST http://localhost:1337/api/articles title=TestArticle author='John Doe' description='lorem ipsum dolar sit amet' images:='[{"kind":"thumbnail", "url":"http://habrahabr.ru/images/write-topic.png"}, {"kind":"detail", "url":"http://habrahabr.ru/images/write-topic.png"}]'

看截图:

然后进入到了virtual studio code里面的断点:

怎么保证其安全性呢? 我用的是oauth2orize, https://www.npmjs.com/package/oauth2orize

在调用的时候加入:

router.post('/', passport.authenticate('bearer', { session: false }), function(req, res) {

然后调用的时候,需要加入token:

william@ubuntu:~$ http POST http://localhost:1337/api/articles title=NewArticle author='John Doe' description='Lorem ipsum dolar sit amet' images:='[{"kind":"thumbnail", "url":"http://habrahabr.ru/images/write-topic.png"}, {"kind":"detail", "url":"http://habrahabr.ru/images/write-topic.png"}]' Authorization:'Bearer put your token here'

passport 与oauth2orize 联合使用,其中有2个重要的概念AccessToken 和 RefreshToken, 为什么有了AccessToken还需要RefreshToken呢?因为token都会过期,需要运用RefreshToken去刷新AccessToken

var oauth2orize = require('oauth2orize');
var passport = require('passport');
var crypto = require('crypto'); var libs = process.cwd() + '/libs/'; var config = require(libs + 'config');
var log = require(libs + 'log')(module); var db = require(libs + 'db/mongoose');
var User = require(libs + 'model/user');
var AccessToken = require(libs + 'model/accessToken');
var RefreshToken = require(libs + 'model/refreshToken'); // create OAuth 2.0 server
var aserver = oauth2orize.createServer(); // Generic error handler
var errFn = function (cb, err) {
if (err) {
return cb(err);
}
}; // Destroys any old tokens and generates a new access and refresh token
var generateTokens = function (data, done) { // curries in `done` callback so we don't need to pass it
var errorHandler = errFn.bind(undefined, done),
refreshToken,
refreshTokenValue,
token,
tokenValue; RefreshToken.remove(data, errorHandler);
AccessToken.remove(data, errorHandler); tokenValue = crypto.randomBytes(32).toString('hex');
refreshTokenValue = crypto.randomBytes(32).toString('hex'); data.token = tokenValue;
token = new AccessToken(data); data.token = refreshTokenValue;
refreshToken = new RefreshToken(data); refreshToken.save(errorHandler); token.save(function (err) {
if (err) { log.error(err);
return done(err);
}
done(null, tokenValue, refreshTokenValue, {
'expires_in': config.get('security:tokenLife')
});
});
}; // Exchange username & password for access token.
aserver.exchange(oauth2orize.exchange.password(function(client, username, password, scope, done) { User.findOne({ username: username }, function(err, user) { if (err) {
return done(err);
} if (!user || !user.checkPassword(password)) {
return done(null, false);
} var model = {
userId: user.userId,
clientId: client.clientId
}; generateTokens(model, done);
}); })); // Exchange refreshToken for access token.
aserver.exchange(oauth2orize.exchange.refreshToken(function(client, refreshToken, scope, done) { RefreshToken.findOne({ token: refreshToken, clientId: client.clientId }, function(err, token) {
if (err) {
return done(err);
} if (!token) {
return done(null, false);
} User.findById(token.userId, function(err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false); } var model = {
userId: user.userId,
clientId: client.clientId
}; generateTokens(model, done);
});
});
})); // token endpoint
//
// `token` middleware handles client requests to exchange authorization grants
// for access tokens. Based on the grant type being exchanged, the above
// exchange middleware will be invoked to handle the request. Clients must
// authenticate when making requests to this endpoint. exports.token = [
passport.authenticate(['basic', 'oauth2-client-password'], { session: false }),
aserver.token(),
aserver.errorHandler()
];

创建AccessToken和RefreshToken

http POST http://localhost:1337/api/oauth/token grant_type=password client_id=android client_secret=SomeRandomCharsAndNumbers username=myapi password=abc1234
http POST http://localhost:1337/api/oauth/token grant_type=refresh_token client_id=android client_secret=SomeRandomCharsAndNumbers refresh_token=[TOKEN]

怎么调试nodejs restful API 以及API的Authorization的更多相关文章

  1. Node与apidoc的邂逅——NodeJS Restful 的API文档生成

    作为后台根据需求文档开发完成接口后,交付给前台(angular vue等)做开发,不可能让前台每个接口调用都去查看你的后台代码一点点查找.前台开发若不懂你的代码呢?让他一个接口一个接口去问你怎么调用, ...

  2. Nodejs RESTFul架构实践之api篇(转)

    why token based auth? 此段摘自 http://zhuanlan.zhihu.com/FrontendMagazine/19920223 英文原文 http://code.tuts ...

  3. PHP实现RESTful风格的API实例(三)

    接前一篇PHP实现RESTful风格的API实例(二) .htaccess :重写URL,使URL以 /restful/class/1 形式访问文件 Options +FollowSymlinks R ...

  4. PHP实现RESTful风格的API实例(二)

    接前一篇PHP实现RESTful风格的API实例(一) Response.php :包含一个Request类,即输出类.根据接收到的Content-Type,将Request类返回的数组拼接成对应的格 ...

  5. PHP实现RESTful风格的API实例(一)

    最近看了一些关于RESTful的资料,自己动手也写了一个RESTful实例,以下是源码 目录详情: restful/ Request.php 数据操作类 Response.php 输出类 index. ...

  6. RESTful 良好的API设计风格

    1.使用名词而不是动词 Resource资源 GET读 POST创建 PUT修改 DELETE /cars 返回 cars集合 创建新的资源 批量更新cars 删除所有cars /cars/711 返 ...

  7. PHP实现Restful风格的API

    Restful是一种设计风格而不是标准,比如一个接口原本是这样的: http://www1.qixoo.com/user/view/id/1表示获取id为1的用户信息,如果使用Restful风格,可以 ...

  8. restful风格的API

    在说restful风格的API之前,我们要先了解什么是rest.什么是restful.最后才是restful风格的API! PS(REST:是一组架构约束条件和原则,REST是Roy Thomes F ...

  9. [01] 浅谈RESTful风格的API

    1.什么是RESTful风格的API REST,即Representational State Transfer,可以理解为"(资源的)表现层状态转化". 在网络上,我们通过浏览器 ...

随机推荐

  1. Python教程(1.1)——配置Python环境

    在正式开始学习Python之前我们需要先配置好Python环境. Python Python可以从Python官方网站上,选择适合你的操作系统的版本下载.下载完之后,运行下载的可执行文件进行安装. 这 ...

  2. Docker - docker machine

    前言 之前在使用docker的时候,对于docker-machine的理解有一些误解(之前一直以为docker-machine和docker-engine等价的,只不过是在window或者mac平台上 ...

  3. 关于echarts使用的常见问题总结

    关于echarts使用的问题总结1.legend图例不显示的问题: 在legend中的data为一个数组项,数组项通常为一个字符串,每一项需要对应一个系列的 name,如果数组项的值与name不相符则 ...

  4. lucene全文搜索之二:创建索引器(创建IKAnalyzer分词器和索引目录管理)基于lucene5.5.3

    前言: lucene全文搜索之一中讲解了lucene开发搜索服务的基本结构,本章将会讲解如何创建索引器.管理索引目录和中文分词器的使用. 包括标准分词器,IKAnalyzer分词器以及两种索引目录的创 ...

  5. linux定时任务访问url

    这次linux定时任务设置成功,也算是自己学习linux中一个小小的里程碑.:) 撒花撒花--- 以下操作均是在ubuntu 下操作的,亲测有效,其他的linux系统还望亲们自己去查.鞠躬感谢! 1 ...

  6. win8安装sql2008及设置登陆名问题

    1. .net3.5安装        使用win8系统自带的升级功能无法成功安装.其实Windows8安装文件中已经集了.Net3.5,       (1)此时只需要使用虚拟光驱加载Windows8 ...

  7. [译]WPF MVVM 架构 Step By Step(5)(添加actions和INotifyPropertyChanged接口)

    应用不只是包含textboxs和labels,还包含actions,如按钮和鼠标事件等.接下来我们加上一些像按钮这样的UI元素来看MVVM类怎么演变的.与之前的UI相比,这次我们加上一个"C ...

  8. 用Nodejs做一个简单的小爬虫

    Nodejs将JavaScript语言带到了服务器端,作为js主力用户的前端们,因此获得了服务器端的开发能力,但除了用express搭建一个博客外,还有什么好玩的项目可以做呢?不如就做一个网络爬虫吧. ...

  9. 使用Github+Hexo框架搭建部署自己的博客

    前言 Hexo 是一个快速.简洁且高效的博客框架.Hexo 使用 Markdown (或其他渲染引擎 )解析文章, 在几秒内,即可利用靓丽的主题生成静态网页. 安装 安装前提 安装 Hexo 相当简单 ...

  10. DDD领域驱动之干活(四)补充篇!

    距离上一篇DDD系列完结已经过了很长一段时间,项目也搁置了一段时间,想想还是继续完善下去. DDD领域驱动之干货(三)完结篇! 上一篇说到了如何实现uow配合Repository在autofac和au ...