2016-11-16 96 views
-1

我想灰燼,數據Express.JS支持的JSON-API鏈接。灰燼,數據工作使用JSON-API


我知道這些......

modelsadaptersserializers

...但他們是如何共同努力?它們如何適合整個Ember.JS


如何設置JSON-API和Ember.JS之間的安全連接

+0

有你通過[指南](https://guides.emberjs.com/v2.9.0/)工作?可以使用「HTTPS」建立安全連接。如果你想認證,有很多選項,包括但不限於'ember-simple-auth'。通常'模型'是關於你有什麼樣的數據,''適配器'在哪裏找到數據,'串行器'是如何被格式化/序列化的。 – Lux

+0

我已閱讀大部分指南。感謝您的評論(勒克斯),但我想有一個答案(更詳細)...謝謝。 – Timo

+0

我懷疑你會得到一個。這個問題太廣泛了。如果你想知道燼內部閱讀代碼,並且如果你有使用它的問題嘗試具體,顯示一些代碼,並描述你有問題。 – Lux

回答

2

這是一個非常廣泛的問題,但最近經歷了這一切,我相信我可以提供一個詳細的迴應,我如何我已經執行它。這是關鍵,因爲有很多選項,如果你查看大部分教程,他們主要關注的是使用rails作爲後端而不是nodeexpress.js。我將根據您使用express.js回答這個問題。

我會記住ember-data是一個完全不同的餘燼,如果你覺得你的項目不需要它的功能,而只是使用AJAX請求,那麼你可以繞過並完全不使用它。 ember-data爲項目的初始啓動增加了很多複雜性和開銷。另外TLS/SSL是您可以擁有的最重要的安全保障,如果沒有安全保障,除此之外,任何數量的嘗試安全保護都是無效的。現在已經完成,讓我們開始設置它的重要部分。

默認ember-data使用基於JSON API specificationJSONAPIAdapter。你Express.js API服務器將必須能夠如果使用默認Adapter沒有Serializer運作這個規格的變化

打破該項目伸到核心部件,他們需要做什麼,以及可供選擇的方案是以下(用我粗體做的):

  • 快遞。JS API服務器
    • 快遞API路線
    • 認證庫
      • 護照是非常適用於express.js
      • 定製
    • 認證機制
      • 基於令牌
      • 曲奇基於
    • 數據建模
      • 蒙戈
      • Sequelize
      • 其他
  • Ember.js基於Web服務器
    • 適配器(這個處理與發送/接收數據和處理錯誤)
      • 應用。JS:爲整個應用程序
    • 串行(這涉及從適配器燼可用使數據)所需的默認
    • 驗證器(這個
        配置適配器
      • ember-simple-auth效果不錯
      • 建立自己的:example
    • 授權者
      • ember-simple-auth-token使用基於令牌認證
  • 數據庫
    • 的MongoDB(基於DOC-非關係型數據庫)
    • 給你一個預置的授權Redis(在內存非關係數據庫中ASE)
    • 的MySQL(關係數據庫)
    • 的PostgreSQL(關係數據庫)
    • 其他

基本流程如下:

  • 用戶試圖登錄在ember.js應用
  • Ember.js使用AUT henticator請求從API服務器訪問
  • API服務器驗證用戶和頭部返回JSON網絡令牌
  • Ember.js使用授權,並增加了JSON網絡令牌頭爲未來的API請求
  • API調用的API做通過與授權報頭中的適配器從灰燼服務器
  • API服務器驗證令牌,並且用於數據的搜索所需
  • API服務器與JSON API規範格式
  • Ember.js適配器接收的數據並處理響應
  • 數據來響應個
  • Ember.js串行器從適配器接收數據,並使其可用由灰燼
  • 灰燼數據從串行器和存儲接收模型數據它在高速緩存中
  • 模型數據基於在灰燼模板和控制器被填充。JS網頁

以下是我設置它

**設置Ember.js爲使用Express.js API服務器**

安裝下列物品燼-CLI:

ember install ember-simple-auth - 對於身份驗證
ember install ember-simple-auth-token - 用於基於令牌的身份驗證

app/adapters/application.js

import DS from 'ember-data'; 
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin'; // Authenticating data from the API server 
import Ember from 'ember'; 
import ENV from '../config/environment'; 

export default DS.JSONAPIAdapter.extend(DataAdapterMixin,{ 

    authManager: Ember.inject.service('session'), 

    host: ENV.apihost, // location of the API server 
    namespace: ENV.apinamespace, // Namespace of API server ie: 'api/v1' 
    authorizer: 'authorizer:token', // Authorizer to use for authentication 

    ajax: function(url, method, hash) { 
    hash = hash || {}; // hash may be undefined 
    hash.crossDomain = true; // Needed for CORS 
    return this._super(url, method, hash); 
    } 
}); 

config/environment.js

ENV.host = 'http://localhost:4000'; /* this assumes the express.js server 
is running on port 4000 locally, in a production environment it would point 
to https://domainname.com/ */ 
ENV['ember-simple-auth'] = { 
    authorizer: 'authorizer:token', //uses ember-simple-auth-token authorizer 
    crossOriginWhitelist: ['http://localhost:4000'], // for CORS 
    baseURL: '/', 
    authenticationRoute: 'login', // Ember.js route that does authentication 
    routeAfterAuthentication: 'profile', // Ember.js route to transition to after authentication 
    routeIfAlreadyAuthenticated: 'profile' // Ember.js route to transition to if already authenticated 
}; 

ENV['ember-simple-auth-token'] = { 
    serverTokenEndpoint: 'http://localhost:4000/auth/token', // Where to get JWT from 
    identificationField: 'email', // identification field that is sent to Express.js server 
    passwordField: 'password', // password field sent to Express.js server 
    tokenPropertyName: 'token', // expected response key from Express.js server 
    authorizationPrefix: 'Bearer ', // header value prefix 
    authorizationHeaderName: 'Authorization', // header key 
    headers: {}, 
}; 
ENV['apihost'] = "http://localhost:4000" // Host of the API server passed to `app/adapters/application.js` 
ENV['apinamespace'] = ""; // Namespace of API server passed to `app/adapters/application.js` 

**設置Express.js服務器**

需要的軟件包:

express:自我解釋
body-parser:解析JSON來自ember.js網站
cors:針對CORS支持
ejwt:對於需要JWT大多數航線的API服務器
passport:驗證用戶
passport-json:驗證用戶
bcrypt:對哈希/醃製用戶密碼
sequelize :用於數據建模

**設置server.js **

var express = require('express'); // App is built on express framework 
var bodyParser = require('body-parser'); // For parsing JSON passed to use through the front end app 
var cors = require('cors'); // For CORS support 
var ejwt = require('express-jwt'); 
var passport = require('passport'); 
// Load Configuration files 
var Config = require('./config/environment'), 
    config = new Config // Load our Environment configuration based on NODE_ENV environmental variable. Default is test. 
var corsOptions = { 
    origin: config.cors 
};  
var app = express(); // Define our app object using express 
app.use(bodyParser.urlencoded({extended: true})); // use x-www-form-urlencoded used for processing submitted forms from the front end app 
app.use(bodyParser.json()); // parse json bodies that come in from the front end app 
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // THIS ALLOWS ACCEPTING EMBER DATA BECAUSE JSON API FORMAT 
app.use(cors(corsOptions)); // Cross-Origin Resource Sharing support 
app.use(passport.initialize()); // initialize passport 
app.use(ejwt({ secret: config.secret}).unless({path: ['/auth/token', { url : '/users', methods: ['POST']}]})); 
require('./app/routes')(app); // Load our routes file that handles all the API call routing 
app.listen(config.port); // Start our server on the configured port. Default is 4000 
console.log('listening on port : ' + config.port); 

config/passport.js

// config/passport.js 
// Configure Passport for local logins 

// Required Modules 
var JsonStrategy = require('passport-json').Strategy; 

// 
var User = require('../app/models/users'); // load user model 

// Function 
module.exports = function (passport) { 
// serialize the user for the session 
passport.serializeUser(function (user, done) { 
    done(null, user.id); 
}); 

// deserialize the user 
passport.deserializeUser(function (id, done) { 
    User.findById(id).then(function (user) { 
     done(null, user); 
    }); 
}); 
// LOCAL LOGIN ========================================================== 
passport.use('json', new JsonStrategy({ 
    usernameProp : 'email', 
    passwordProp : 'password', 
    passReqToCallback : true 
}, 
function (req, email, password, done) { 
    User.findOne({where : {'email' : email }}).then(function (user) { // check against email 
     if (!user) { 
      User.findOne({where : {'displayName' : email}}).then(function(user){ //check against displayName 
      if (!user) return done(null, false); 
      else if (User.validatePassword(password,user.password)) return done(null, user); 
      else return done(null, false); 
      }); 
     } 
     else if (User.validatePassword(password,user.password)) return done(null, user); 
     else return done(null, false); 
    }); 
})); 
}; 

app/models/users.js用戶sequelize模型

// Load required Packages 
var Sequelize = require('sequelize'); 
var bcrypt = require('bcrypt-node') 
// Load required helpers 
var sequelize = require('../helpers/sequelizeconnect'); 
var config = new require('../../config/environment'); // Load our Environment configuration based on NODE_ENV environmental variable. Default is test. 

// Load other models 

// Define model 
var Users = sequelize.define('users', { 
    "email": { type: Sequelize.STRING}, // user email 
    "password": { type: Sequelize.STRING} // user password 
}); 

// Methods ======================================================= 

// Hash a password before storing 
Users.generateHash = function(password) { 
    return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null); 
}; 

// Compare a password from the DB 
Users.validatePassword = function(password, dbpassword) { 
    return bcrypt.compareSync(password, dbpassword); 
} 

module.exports = Users 

此時您express.js服務器將只需要你routes.js設置與你的API服務器需要的路線,在爲了執行認證,最少需要/auth/token。一個成功的響應Ember.js JSON API接口預期的一個例子是:

var jsonObject = { // create json response object 
    "data": { 
     "type": "users", // ember.js model 
     "id": 1, // id of the model 
     "attributes": { 
      "email" : "[email protected]", 
     } 
    } 
} 
res.status(201).json(jsonObject); // send new data object with 201/OK as a response 

還有很多更復雜,以建立JSON API服務器響應請求刪除,確認錯誤等