我想灰燼,數據與Express.JS支持的JSON-API鏈接。灰燼,數據工作使用JSON-API
我知道這些......
models
adapters
serializers
...但他們是如何共同努力?它們如何適合整個Ember.JS?
如何設置JSON-API和Ember.JS之間的安全連接?
我想灰燼,數據與Express.JS支持的JSON-API鏈接。灰燼,數據工作使用JSON-API
我知道這些......
models
adapters
serializers
...但他們是如何共同努力?它們如何適合整個Ember.JS?
如何設置JSON-API和Ember.JS之間的安全連接?
這是一個非常廣泛的問題,但最近經歷了這一切,我相信我可以提供一個詳細的迴應,我如何我已經執行它。這是關鍵,因爲有很多選項,如果你查看大部分教程,他們主要關注的是使用rails
作爲後端而不是node
或express.js
。我將根據您使用express.js
回答這個問題。
我會記住ember-data
是一個完全不同的餘燼,如果你覺得你的項目不需要它的功能,而只是使用AJAX請求,那麼你可以繞過並完全不使用它。 ember-data
爲項目的初始啓動增加了很多複雜性和開銷。另外TLS/SSL是您可以擁有的最重要的安全保障,如果沒有安全保障,除此之外,任何數量的嘗試安全保護都是無效的。現在已經完成,讓我們開始設置它的重要部分。
默認ember-data
使用基於JSON API specification的JSONAPIAdapter
。你Express.js
API服務器將必須能夠如果使用默認Adapter
沒有Serializer
運作這個規格的變化
打破該項目伸到核心部件,他們需要做什麼,以及可供選擇的方案是以下(用我粗體做的):
express.js
ember-simple-auth
效果不錯ember-simple-auth-token
使用基於令牌認證基本流程如下:
以下是我設置它
**設置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服務器響應請求刪除,確認錯誤等
有你通過[指南](https://guides.emberjs.com/v2.9.0/)工作?可以使用「HTTPS」建立安全連接。如果你想認證,有很多選項,包括但不限於'ember-simple-auth'。通常'模型'是關於你有什麼樣的數據,''適配器'在哪裏找到數據,'串行器'是如何被格式化/序列化的。 – Lux
我已閱讀大部分指南。感謝您的評論(勒克斯),但我想有一個答案(更詳細)...謝謝。 – Timo
我懷疑你會得到一個。這個問題太廣泛了。如果你想知道燼內部閱讀代碼,並且如果你有使用它的問題嘗試具體,顯示一些代碼,並描述你有問題。 – Lux