Node.JS, Mongoose和Jade搭建OAuth2服務(wù)器
今天我們來看一個(gè)Node.JS的實(shí)際應(yīng)用。這是國外的Paper應(yīng)用開發(fā)者所搭建的OAuth2服務(wù)器,使用的主要技術(shù)包括:
- Node.JS 的Express框架
- Mongoose工具集,Mongodb的一個(gè)流行庫,方便建立模型。
- bcrypt,用于密碼加密
- superagent,用于測(cè)試
Papers是一項(xiàng)論文數(shù)據(jù)庫移動(dòng)應(yīng)用,有iOS和Android版本。寫論文的同學(xué)們會(huì)很需要,關(guān)于它的介紹,請(qǐng)看開發(fā)者的官方博客。http://blog.papersapp.com/oauth-server-in-node-js/
雖然Papers并不是開源的,但是作者已經(jīng)把寫好的node-oauth2-server模塊以及Papers的認(rèn)證過程一起打包放在了GitHub上,我們可以下載研究:
https://github.com/mekentosj/oauth2-example
在代碼中的Models目錄下,我們可以清楚的看到Model的Schema定義。從這里,我們可以明白OAuth2的需要處理的主要數(shù)據(jù)結(jié)構(gòu),包括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
- });
通過運(yùn)行代碼中的seed.js,我們創(chuàng)建了一個(gè)user.
- var app = require('./app');
- var models = require('./models');
- models.User.create({
- email: 'alex@example.com',
- hashed_password: '$2a$10$aZB36UooZpL.fAgbQVN/j.pfZVVvkHxEnj7vfkVSqwBOBZbB/IAAK'
- }, function() {
- models.OAuthClientsModel.create({
- clientId: 'papers3',
- clientSecret: '123',
- redirectUri: '/oauth/redirect'
- }, function() {
- process.exit();
- });
- });
這樣我們就可以開始體驗(yàn)這個(gè)Node.JS的OAuth2服務(wù)器了。先讓Mongo運(yùn)行起來,負(fù)責(zé)后臺(tái)數(shù)據(jù)庫, 比如"mongod -dbpath ./", 之后運(yùn)行"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
模擬一個(gè)Oauth2的access token請(qǐng)求,運(yùn)行這份文件(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形式組合并轉(zhuǎn)換成Base64-encoded
- var clientCredentials = (t_client_id + ':'+t_client_secret).toString('base64');
- //用戶名
- var t_username = 'alex@example.com';
- //密碼
- var t_password = 'test';
- console.log(clientCredentials);
- //發(fā)送Post請(qǐng)求獲取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
原文鏈接:http://blog.csdn.net/u011581005/article/details/23650917