Node.JS, Mongoose和Jade搭建OAuth2服务器

86911031 2014-04-21

今天我们来看一个Node.JS的实际应用。这是国外的Paper应用开发者所搭建的OAuth2服务器,使用的主要技术包括:

- Node.JS 的Express框架

- Mongoose工具集,Mongodb的一个流行库,方便建立模型。

- bcrypt,用于密码加密

- superagent,用于测试

Papers是一项论文数据库移动应用,有iOS和Android版本。写论文的同学们会很需要,关于它的介绍,请看开发者的官方博客。http://blog.papersapp.com/oauth-server-in-node-js/

虽然Papers并不是开源的,但是作者已经把写好的node-oauth2-server模块以及Papers的认证过程一起打包放在了GitHub上,我们可以下载研究:

https://github.com/mekentosj/oauth2-example

在代码中的Models目录下,我们可以清楚的看到Model的Schema定义。从这里,我们可以明白OAuth2的需要处理的主要数据结构,包括access_token, refresh_token, oauth_client.

var OAuthAccessTokensSchema = new Schema({  



  accessToken: { type: String, required: true, unique: true },  



  clientId: String,  



  userId: { type: String, required: true },  



  expires: Date  


});  


 



var OAuthRefreshTokensSchema = new Schema({  




  refreshToken: { type: String, required: true, unique: true },  



  clientId: String,  



  userId: { type: String, required: true },  



  expires: Date  


});  


 



var OAuthClientsSchema = new Schema({  



  clientId: String,  


  clientSecret: String,  


  redirectUri: String  


});  


 



var OAuthUsersSchema = new Schema({  




  email: { type: String, unique: true, required: true },  




  hashed_password: { type: String, required: true },  




  password_reset_token: { type: String, unique: true },  



  reset_token_expires: Date,  


  firstname: String,  


  lastname: String  


}); 

通过运行代码中的seed.js,我们创建了一个user.

var app = require('./app');  



var models = require('./models');  



 


models.User.create({  



  email: '[email protected]',  




  hashed_password: '$2a$10$aZB36UooZpL.fAgbQVN/j.pfZVVvkHxEnj7vfkVSqwBOBZbB/IAAK' 




}, function() {  



  models.OAuthClientsModel.create({  



    clientId: 'papers3',  




    clientSecret: '123',  




    redirectUri: '/oauth/redirect' 




  }, function() {  



    process.exit();  


  });  


}); 

这样我们就可以开始体验这个Node.JS的OAuth2服务器了。先让Mongo运行起来,负责后台数据库, 比如"mongod -dbpath ./", 之后运行"npm start".

oliverluan@localhost:~/Documents/EvWork/node_oauth2_example/oauth2-example$ npm start  


 


> [email protected] start /Users/oliverluan/Documents/EvWork/node_oauth2_example/oauth2-example  


> ./node_modules/.bin/nodemon server.js  


 


14 Apr 07:02:43 - [nodemon] v1.0.17  


14 Apr 07:02:43 - [nodemon] to restart at any time, enter `rs`  


14 Apr 07:02:43 - [nodemon] watching: *.*  


14 Apr 07:02:43 - [nodemon] starting `node server.js`  



connect.multipart() will be removed in connect 3.0  




visit https://github.com/senchalabs/connect/wiki/Connect-3.0 for alternatives  




connect.limit() will be removed in connect 3.0  



Express server listening on port: 3000  


POST /oauth/token 200 102ms - 175b  


GET /secret 200 2ms - 11b 

模拟一个Oauth2的access token请求,运行这份文件(node getToken.js)

var request = require('request');  


 



//client_id  




var t_client_id = 'papers3';  




//client_secret  




var t_client_secret = '123';  




//clientCredentials  以client_id:client_secret形式组合并转换成Base64-encoded  




var clientCredentials = (t_client_id + ':'+t_client_secret).toString('base64');  




//用户名  




var t_username = '[email protected]';  




//密码  




var t_password = 'test';  



 


console.log(clientCredentials);  


 



//发送Post请求获取Token  



request.post({    



  url: 'http://' + clientCredentials + '@localhost:3000/oauth/token',  



  form: {  



    grant_type: 'password',  



    username: t_username,  


    password: t_password,  


    client_id: t_client_id,  


    client_secret: t_client_secret  


  },  



}, function(err, res, body) {  



  console.log(body);  



  //获得Token  




  var accessToken = JSON.parse(body).access_token;  



 


  request.get({  



    url: 'http://localhost:3000/secret',  




    headers: { Authorization: 'Bearer ' + accessToken }  




  }, function(err, res, body) {  



    console.log(body);  


   });  


});  

成功获得access token.

相关推荐