今天我们来看一个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: 'alex@cdxwcx.com',
 - 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
 - > oauth2-experiment@0.0.1 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 = 'alex@cdxwcx.com';
 - //密码
 - 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.
- oliverluan@localhost:~/Documents/EvWork/node_oauth2_example/oauth2-example$ node getToken.js
 - papers3:123
 - {
 - "token_type": "bearer",
 - "access_token": "620bb362f32857d5174802e06065305874953597",
 - "expires_in": 3600,
 - "refresh_token": "569be5f4cc1ea943021b3676eaa2a51825c2c257"
 - }
 - Secret area
 
Copyright © 2009-2022 www.wtcwzsj.com 青羊区广皓图文设计工作室(个体工商户) 版权所有 蜀ICP备19037934号