Nodejs快速搭建简单Oauth认证和restful API server攻略。

Nodejs快速搭建简单Oauth认证和restful API server攻略。

最近一直在鼓捣这个东西,拿出来分享下一下经验吧,其实很简单,一点也不难。

首先需求是这样,给自己的网站要增加API服务,API分为两种,公共的和私有授权的,授权的使用Oauth方法认证身份,API格式均为JOSN和JSONP。

嗯,别的语言我也没怎么学过,首先是找合适的框架进行实现吧。本身网站使用的express2.x开发的,再在express2.x的基础上开发api接口感觉太累了,找到了社区推荐的restify http://mcavage.github.io/node-restify/ 进行API开发,然后又搜到了一个开源的oauth的express中间件,https://github.com/ammmir/node-oauth2-provider

数据源是mongodb,那么开搞吧。

首先是把api的策略和需求文档整理出来,这里有个还没开发完的例子:

https://github.com/xiaojue/tuer.me/blob/master/docs/index.md

首先是授权方法和api讲解,然后是api列表和实现地址与接口简单说明,参数说明等。

当然这写都是在开始写api之前要先大概设计好的。参见上面的地址。我也是参考了别的网站的api文档自己胡乱写的。大概就那么个意思吧。。

然后在说具体开发的细节时,得先讲明白啥是Oauth认证和restful,百科上有官方解释,我就不自己忽悠了。我在这里说下自己的白话理解。

首先restful是api的格式和规范,使用restify应该是帮你会保持好格式和一些特定的特征的,这里我没做过多了解,文档实在太多。。我只知道就像普通网站开发一下,写好json接口就好了。

但是这写api需要认证使用者的身份,这里的使用者分为2种身份,一种为api调用程序,也就是开发者写的代码,一种是使用程序的普通用户的身份需要验证。

对程序的认证,我使用appkey和secret的方式认证,没有这2个,是不允许请求api的。

appkey和secret简单来说就是对程序的另外一份密码和帐号的实现。当开发者申请了一个appkey的时候,我通过算法来进行生成这2个东东,在程序请求api的时候通过对这2个的核对,来确保程序来源。

首先在自己网站上要先写一个申请api的服务,然后做一个简单的后台对申请后的应用就行审核,审核其实就是生成appkey和secret的过程。

应用拥有了appkey和secret之后,公开的api可以直接用参数带appkey的方式获取资源。授权api则需要通过用户授权了,这里就需要用到secret了。

具体流程是:

用户使用第三方应用之前,第三方应用给出本站的一个授权页面地址,参数夹带appkey和回调地址,回调地址和之前申请的地址要一致,确保不会被钓鱼。

用户抵达我的站点授权应用之后,我会把浏览器重新定向到那个回调地址,带一个临时的code码,这个code码是和appkey成对应的。

第三方应用把这个code码获取之后,用这个code码加appkey加程序的secret,来本站换取用户的token,这个时候的secret不会对外部有暴露,就像密码一样,post给我,我再和对code和secret信息,完成对appkey的第二次校验,之后根据这个用户的特征给这个用户生成一个token,2份,我本地一份,第三方一份。

这个token就是用于校验用户身份的了,算法一般是采用可逆的加密方式,但是要有密钥才可以解开的。这里就不详细说了,可以自行搜索serializer这个模块,就是干这个的。

token在加密的时候,本身会注入一些信息,比如这个用户的id,生成时间戳,以及其他一些你觉得有用的信息。

在下次第三方应用发token换取授权api的时候,主站可以解开这个token,核对时间戳【看token的有效期是否合法】看id是否存在,检查一些其他隐藏属性是否被修改等,来进行再次身份确认。

我的程序token是100天的有效期。当然还会提供刷新token的方法,方法就和上面的过程类似了,拿老token换新token,2边同步下即可。

ok,oauth算是大概说明白流程了。上面看起来很复杂的,但是有了最开始说的2个模块之后,很多事情就不需要自己来干了。

这里给出2个参考文件:

https://github.com/xiaojue/tuer.me/blob/master/lib/OAP.js

这个是oauth在主站的路由控制,详细api可以见oauth2-provider的项目例子。里面提供生成token的方法,生成授权表单的路由,对header拦截和校验的功能等。很方便,只需要自己相应填空就行,当然要结合自己网站的数据进行查询和校验。

还有一个就是api的实现了,restify有不少的坑需要一一说明,首先是对中文的实现,编码utf-8在官方的例子是设置req.setChart 但是,真正的最新2.x版本又去掉了这个功能,所以必须自己手动设置。

还有就是对oauth2的支持也并不好,如果用他的Authorization header parsing插件,对token放在url中,或者可能自己需要扩展的认证方法,很难修改【要改他的源码。你pull request了吧,人家肯定也不收。。】所以我是自己用restify的use自己写了一个,参考代码如下:

https://github.com/xiaojue/tuer.me/blob/master/api.js#L75

写的很搓。。不过很通俗易懂了。。大概就是校验几个接受token的地方,然后解开token进行核对确认身份,再看是否需要拦截。

当然在具体的api接口中,还是需要再次确认了,比如一个api,是修改用户资料,那么应用传了一个token,虽然合法,但是可能不是这个用户的token,所以还是需要在api中需要的地方再次进行身份认证。

所以我在req.authorization又进行了token的存储。方便在接口中再次获取校验。

ok,然后就是编写你自己的业务api了,和写网站差不多,语法和思路和express也是一样的。再给一个例子:

https://github.com/xiaojue/tuer.me/blob/master/routes/apis/feed.js

这是网站feed的api实现,一看就很简单了。。需要注意的是,在往外吐的时候,还是要配置个白名单。否则获取用户信息把pwd也反回去就囧了。。

ok。再详细的攻略等我把api全部开发好了,上线之后再上 客户端的demo例子吧。

嘛,代码写的很搓,纯属娱乐,切勿较真。。


14 回复

Node.js 快速搭建简单OAuth认证和RESTful API服务器攻略

引言

最近一直在研究如何快速搭建一个支持OAuth认证和RESTful API的服务器。这篇文章将分享我的经验和过程,希望能帮助大家快速入门。

需求概述

需求是这样的:给自己的网站增加API服务,API分为两种:公共的和私有的(需要OAuth认证)。API的格式均为JSON和JSONP。

技术选型

由于我的网站是基于Express 2.x开发的,但为了更高效地开发API,我选择了社区推荐的restify框架。同时,我也找到了一个名为node-oauth2-provider的开源中间件来处理OAuth认证。

数据库

数据库选用MongoDB。

开发步骤

  1. API策略和需求文档

    • 在开始编写API之前,首先要整理出API的策略和需求文档。例如,参考这个文档
  2. OAuth认证

    • OAuth是一种授权协议,用于允许第三方应用访问用户资源,而无需透露用户的密码。
    • 使用node-oauth2-provider来简化OAuth认证流程。
    • 具体流程包括:
      • 用户通过第三方应用访问授权页面。
      • 第三方应用传递appkey和回调地址。
      • 用户同意授权后,系统重定向到回调地址,并附带一个临时的code码。
      • 第三方应用使用codeappkeysecret换取用户的token
      • token用于后续的API调用,验证用户身份。
  3. RESTful API开发

    • 使用restify框架来构建API。
    • 示例代码:
const restify = require('restify');
const server = restify.createServer();

// 设置响应头
server.use(restify.plugins.acceptParser(server.acceptable));
server.use(restify.plugins.queryParser());
server.use(restify.plugins.bodyParser());

// 自定义token验证中间件
function authenticateToken(req, res, next) {
    const token = req.headers['x-access-token'] || req.query.token;
    if (!token) return res.send(401, 'Unauthorized');

    // 解析token并验证
    try {
        const decoded = jwt.verify(token, process.env.JWT_SECRET);
        req.user = decoded;
        next();
    } catch (err) {
        return res.send(401, 'Invalid token');
    }
}

// 使用中间件
server.use(authenticateToken);

// 示例API路由
server.get('/api/users/:id', (req, res, next) => {
    const userId = req.params.id;
    // 查询用户信息
    User.findById(userId, (err, user) => {
        if (err) return next(err);
        res.json(user);
    });
});

// 启动服务器
server.listen(8080, () => {
    console.log('%s listening at %s', server.name, server.url);
});
  1. 编写业务逻辑
    • 编写具体的API接口,如用户资料修改、获取用户信息等。
    • 示例代码:
const restify = require('restify');

// 示例API路由
server.post('/api/users/:id', (req, res, next) => {
    const userId = req.params.id;
    const { name, email } = req.body;

    // 更新用户信息
    User.findByIdAndUpdate(userId, { name, email }, { new: true }, (err, updatedUser) => {
        if (err) return next(err);
        res.json(updatedUser);
    });
});

总结

通过以上步骤,我们可以快速搭建一个支持OAuth认证和RESTful API的服务器。希望这篇攻略对你有所帮助!如果需要更详细的示例或文档,可以参考这个GitHub仓库


https://github.com/mcavage/node-restify/issues/336

作者已经修改了文章我说的 setChart了。。不过发没发npm就不晓得了。刚看到回复。

这是Oauth1还是Oauth2的?

我只实现了并且就支持 response_type = code 这种授权。oauth2的授权方法貌似有很多,我就选了其中一个支持。

支持,期待更新 ,MARK一个

恩,到时候api都写好,一起写点插件客户端神吗的。。。

code换token的时候,因为是http协议,client_secret在通过POST传输,client_secret会暴露给用户的,安全漏洞!呵呵。

Github项目,已给你发 issue

恩,收到了,不是https的传输协议其实都是不安全的,我打算过阵子登陆和api服务都改成https的。有兴趣你帮我改下更好~ 哈哈哈

🐴 空了看看

来自酷炫的 CNodeMD

Node.js 快速搭建简单OAuth认证和RESTful API Server 攻略

背景

最近一直在鼓捣一个项目,需要给自己的网站添加API服务。这些API分为公共的和需要OAuth认证的私有API。今天就把搭建这个系统的经验分享给大家。

技术选型

  • Web框架:选择了 restify,因为它更适合处理API服务,而不仅仅是网页。
  • OAuth认证:使用了 node-oauth2-server 模块,它提供了完整的OAuth2.0认证支持。

数据库

数据库选用的是 MongoDB,主要因为它的灵活和高效。

开发流程

  1. 整理API策略和需求文档

    • 列出所有API的功能和规格。
    • 创建一个包含所有API端点、参数和返回值的文档。
  2. OAuth认证流程

    • 用户在第三方应用请求授权时,会被重定向到你的网站。
    • 用户授权后,系统生成并返回一个 token 给第三方应用。
    • 第三方应用使用 token 请求私有API。
  3. 编写API

    • 使用 restify 编写RESTful API,确保所有API都遵循RESTful规范。
    • 对于需要认证的API,使用 node-oauth2-server 中间件进行认证。

示例代码

OAuth 认证
const restify = require('restify');
const oauth2orize = require('oauth2orize');
const OAuth2Server = require('oauth2-server');

// 创建OAuth2Server实例
const oauthServer = new OAuth2Server({
    model: require('./models/oauth'),
});

// 在每个请求中使用OAuth中间件
server.use((req, res, next) => {
    return oauthServer.authHandler(req, res, next);
});
RESTful API
const restify = require('restify');

const server = restify.createServer();

server.use(restify.plugins.acceptParser(server.acceptable));
server.use(restify.plugins.queryParser());
server.use(restify.plugins.bodyParser());

server.post('/api/feed', (req, res, next) => {
    // 需要验证token
    if (!req.authorization) {
        return res.send(401, 'Unauthorized');
    }

    // 解析并验证token
    const token = req.authorization.basic.token;
    // 验证逻辑
    // ...
    
    // 如果验证通过
    res.send(200, { message: 'Feed updated successfully' });
    return next();
});

server.listen(3000, () => {
    console.log('%s listening at %s', server.name, server.url);
});

总结

搭建OAuth认证和RESTful API服务器并不复杂,关键是选择合适的工具和框架。restifynode-oauth2-server 是非常不错的选择。希望这篇攻略对你有所帮助!

回到顶部