In LoopBack 4 framework, for any secured API call, I need to authenticate the request for every endpoint. Instead of this approach i wants to configure that verification globally like LoopBack 3. Any solution for this?
#post('/users/{userId}/orders', {
responses: {
'200': {
description: 'User.Order model instance',
content: {'application/json': {schema: {'x-ts-type': Order}}},
},
},
})
#authenticate('jwt')
#authorize({resource: 'order', scopes: ['create']})
async createOrder(
#param.path.string('userId') userId: string,
#requestBody() order: Order,
): Promise<Order> {
await this.userRepo.orders(userId).create(order);
}
In above code #authenticate('jwt') was mentioned, can we mention this in a common file?
Related
This is my viewController:
onRestDeleteClick: function(){
var ouType = Ext.create('MyApp.model.OuType',
{
id: 49,
ouTypeName: 'Lenlee',
entityName: 'Lenlee'
});
ouType.erase();
}
The model whose id is 49 exists in database.
This is the OuType model:
Ext.define('MyApp.model.OuType', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.Field'
],
fields: [
{
name:'id'
},
{
name: 'ouTypeName'
},
{
name: 'entityName'
}
],
proxy:{
type: 'rest',
api: {
read: 'role/read',
update: 'role/update',
create: 'role/create',
destory: 'role/destory'
}
}
});
This is my server class:
#RequestMapping("/role")
#Controller("sysRoleContro")
public class SysRoleController {
…………
…………
#RequestMapping(value="/destory/{id}")
public void destoryOuType(HttpServletRequest request,
HttpServletResponse response, #PathVariable("id") Long id){
log.info("destory");
ouTypeRepository.delete(id);
log.info("end");
}
………
……
}
Now when i click the delete button, the request url is: http://localhost:7080/MyApp.model.OuType/49 404 Not Found.
The expected url is http://localhost:7080/CSQMS/role/destory/49
How can i delete the model?
Rest proxy is special in that that it does not CRUD operations to urls, as you set in api, but to HTTP verbs: GET, POST, PUT, DELETE, etc. So api config is most likely ignored. Configure the proxy this way:
proxy:{
type:'rest',
url:'/CSQMS/role'
}
If your server expects that CRUD operation verb is part of the URL you probably need a different proxy or you need to implement buildUrl method.
I want to say i'm so careless, i should write 'destroy' instead of 'destory'. MY GOD.
I am using ExtJS 5 and I want to access complex REST resources as discussed in this similar thread using ExtJS 4.
The REST service that I am accessing exposes these resources:
GET /rest/clients - it returns a list of clients
GET /rest/users - it returns a list of all users
GET /rest/clients/{clientId}/users - it returns a list of users from the specified client.
I have these models:
Ext.define('App.model.Base', {
extend: 'Ext.data.Model',
schema: {
namespace: 'App.model'
}
});
Ext.define('App.model.Client', {
extend: 'App.model.Base',
fields: [{
name: 'name',
type: 'string'
}],
proxy: {
url: 'rest/clients',
type: 'rest'
}
});
Ext.define('App.model.User', {
extend: 'App.model.Base',
fields: [{
name: 'name',
type: 'string'
},{
name: 'clientId',
reference: 'Client'
}],
proxy: {
url: 'rest/users',
type: 'rest'
}
});
I did this:
var client = App.model.Client.load(2);
var users = client.users().load();
And it sent, respectively:
//GET rest/clients/2
//GET rest/users?filter:[{"property":"personId","value":"Person-1","exactMatch":true}]
Questions:
Is there any way that I can send my request to "GET rest/clients/2/users" without updating the user proxy url manually with its clientId?
How can I send above request without losing the original url defined in App.model.User, "rest/users"
I think this essentially the same as this question:
Accessing complex REST resources with Ext JS
I don't think much has changed since it was first asked.
General Problem
Sails JS is built upon express JS, for debugging reasons I would like to inject a middleware or a function in Sails JS before cookieParser/bodyParser, I expect that Sails JS wrapped the following:
app.use(cookieParser());
app.use(bodyParser());
etc...
I would like to inject my own middleware function before these injections, how can I do that? for example in order to track the initial request.
Specific problem:
I integrated with Passport JS, sensitive users info are in request (see below), I am pretty sure this is due to request parsing middleware like cookieParser/bodyParser, but I would like to know how to confirm this myself.
(I would also be happy for a confirmation from you)
When I print the request, the user information is there, specifically, the password ("password: '$2a$10$rfRptIm7o1BKD1Qdr7yPUeWVisEHyZciCdD0ebivLAm8PPVRUicES',")
Here is the partial request:
_passport:
{ instance:
{ _key: 'passport',
_strategies: [Object],
_serializers: [Object],
_deserializers: [Object],
_infoTransformers: [],
_framework: [Object],
_userProperty: 'user',
Authenticator: [Function: Authenticator],
Passport: [Function: Authenticator],
Strategy: [Object],
strategies: [Object] },
session: { user: '532ea818e6221c90251e9342' } },
user:
{ username: 'nizar',
password: '$2a$10$rfRptIm7o1BKD1Qdr7yPUeWVisEHyZciCdD0ebivLAm8PPVRUicES',
createdAt: Sun Mar 23 2014 11:23:36 GMT+0200 (Jerusalem Standard Time),
updatedAt: Sun Mar 23 2014 11:23:36 GMT+0200 (Jerusalem Standard Time),
id: '532ea818e6221c90251e9342' },
while in the model I toJSON and deleted the password:
toJSON: function() {
var obj = this.toObject();
delete obj.password;
return obj;
}
1.General Problem
For Sails 0.9.x, the middlwares loaded by the sails server are defined in sails/lib/express/index.js. As you can see, the custom middlware defined in config/express.js is used after cookieParser, session, bodyParser and methodOverride. To inject a custom middleware before cookieParser and bodyParser, you can override the cookieParser or modify sails/lib/express/index.js directly.
For Sails 0.10.x, you can define a custom loadMiddleware function (default implementation is in sails/lib/hooks/http/loadMiddleware.js) in config/express.js. Scott Gress has explained this in detail.
2.Specific Problem
If you don't want the request object to include the password information, call toJSON() in the callback function of deserializeUser:
passport.deserializeUser(function(id, done) {
User.findOneById(id).done(function(err, user) {
done(err, user.toJSON());
});
});
and in the callback function of the strategy definition:
passport.use('local',
new LocalStrategy({
usernameField: 'userename',
passwordField: 'password'
},
function(username, password, done) {
User.findOne({ name: username}).done(function(err, user) {
if (err) return done(err);
if (!user) {
return done(null, false, {message: 'Unknown user'+username});
};
if (!user.validatePassword(password)) {
return done(null, false, {message: 'Invalid password!'});
};
return done(null, user.toJSON());
});
}
));
For Sails v0.10, you can follow the procedure in this answer to insert custom middleware before the body parser. In v0.9.x, you'd have to create your own bodyParser callback and add the middleware in there; see this answer for more info.
However in your case I'm not sure any of this is necessary. Passport is adding user data to the request object on the server as a convenience, but it's not actually being transmitted in the request. So, there's no sensitive data out in the open--it's just in memory. Your only concern is to keep it from being sent back to the client, which you're already doing with your toJSON method on the User model.
I am quite new to Node. I came across Sails.js. I think it is based on WebSocket, which seems to be really good for building real-time applications. I would like to know that whether Sails can be used to implement REST architecture as it uses WebSocket? And if yes, how?
Yes it can. Sails JS allows you to easily build a RESTful API, essentially with no effort to get started. Also, websockets (through socket.io) are integrated by default into the view and api.
To create a fully RESTful app from the ground up, it actually requires no JS. Try:
sails new testapp
cd testapp
sails generate model user
sails generate controller user
cd <main root>
sails lift
The CRUD (Create, Read, Update, Delete) actions are already created for you. No code!
You can create a user in your browser by doing the following:
HTTP POST (using a tool like PostMan) to http://:1337/user/create
{
"firstName": "Bob",
"lastName": "Jones"
}
Next, do a GET to see the new user:
HTTP GET http://:1337/user/
FYI - Sails JS uses a default disk based database to get you going
Done.
sails new testapp
cd testapp
sails generate api apiName
controller
create: function (req, res) {
var payload = {
name:req.body.name,
price:req.body.price,
category:req.body.category,
author:req.body.author,
description:req.body.description
};
Book.create(payload).exec(function(err){
if(err){
res.status(500).json({'error':'something is not right'})
}else{
res.status(200).json({'success':true, 'result':payload, 'message':'Book Created success'})
}
});
},
readone: async function (req, res) {
var id = req.params.id;
var fff = await Book.find(id);
if(fff.length == 0){
res.status(500).json({'error':'No record found from this ID'})
}else{
res.status(200).json({'success':true, 'result':fff, 'message':'Record found'})
}
},
model
attributes: {
id: { type: 'number', autoIncrement: true },
name: { type: 'string', required: true, },
price: { type: 'number', required: true, },
category: { type: 'string', required: true, },
author: { type: 'string' },
description: { type: 'string' },
},
routes
'post /newbook': 'BookController.create',
'get /book/:id': 'BookController.readone',
Is there any way to include the 'has many' models in the 'put' request sent using ember data-store REST adapter?
You can have embedded records by defining them on the adapter
Comment = DS.Model.extend({
votes: DS.hasMany(Vote)
});
Adapter.map(Comment, {
votes: { embedded: 'always' }
});
https://github.com/emberjs/data/blob/master/packages/ember-data/tests/integration/embedded/embedded_dirtying_test.js#L53