Closed rishighan closed 4 years ago
I made some progress and now have my login action working temporarily:
login: {
handler(ctx) {
return new Promise((resolve, reject) => {
passport.authenticate("local", (err, user, info) => {
if (err) {
reject(new Error(err));
}
if (!user) {
ctx.meta.$statusCode = 401;
reject({ status: "Invalid credentials" });
}
ctx.options.parentCtx.params.req.logIn(
user,
err,
() => {
if (err) {
ctx.meta.$statusCode = 500;
reject({ status: "Could not login user" });
}
ctx.meta.$statusCode = 200;
resolve({ status: "Login successful" });
}
);
})(
ctx.options.parentCtx.params.req,
ctx.options.parentCtx.params.res,
() => {
console.log("Inside user.login's callback");
}
);
});
},
},
Couple of questions:
req
?undefined
errors when referencing req
I just found out that when I run the service dockerized, the context param of the action handler has a different signature:
Context< {
id: 'fd5f7c87-51db-4e5c-8297-6f1ade4750a9',
nodeID: 'abf3540dd285-18',
action: { name: 'user.status' },
service: { name: 'user', version: undefined, fullName: 'user' },
options: { timeout: 10000, retries: null },
parentID: '621aafc2-a3a4-419b-a630-7a0ac32bc073',
caller: 'api',
level: 2,
params: {},
meta: {},
requestID: '621aafc2-a3a4-419b-a630-7a0ac32bc073',
tracing: true,
span: Span {
name: "action 'user.status'",
type: 'action',
id: 'fd5f7c87-51db-4e5c-8297-6f1ade4750a9',
traceID: '621aafc2-a3a4-419b-a630-7a0ac32bc073',
parentID: '621aafc2-a3a4-419b-a630-7a0ac32bc073',
service: { name: 'user', version: undefined, fullName: 'user' },
priority: 5,
sampled: true,
startTime: 1588806411889.3867,
finishTime: null,
duration: null,
error: null,
logs: [],
tags: {
callingLevel: 2,
action: [Object],
remoteCall: true,
callerNodeID: 'abf3540dd285-18',
nodeID: 'f4fc833ec47f-18',
options: [Object],
params: {}
}
},
needAck: null,
ackID: null,
eventName: null,
eventType: null,
eventGroups: null,
cachedResult: false
} >
Why aren't there req
and res
objects?
The req
& res
instances are not serializable. You can't send them through the transporter. You should use them only in API gateway service locally.
So put the action as a custom function in api.service.js
like this:
"POST login" (req, res) {
return new Promise((resolve, reject) => {
passport.authenticate("local", (err, user, info) => {
if (err) {
reject(new Error(err));
}
if (!user) {
// ctx.meta.$statusCode = 401;
reject({
status: "Invalid credentials"
});
}
req.logIn(
user,
err,
() => {
if (err) {
// ctx.meta.$statusCode = 500;
reject({
status: "Could not login user"
});
}
// ctx.meta.$statusCode = 200;
resolve({
status: "Login successful"
});
}
);
})(
req,
res,
() => {
console.log("Inside user.login's callback");
}
);
});
},
When I hit the endpoint, the request times out. Not sure why...
If you use custom alias, you should handle the response completely, e.g calling res.end()
.
Thanks @icebob! You can mark this as a question, since the req
and res
objects aren't serializable by design.
Is is possible to add the addition http request data as action handler params
?
I need the request headers, cookies, method, baseUrl, and originalUrl.
These fields should be serializable through the transporter.
you should expose these data in onBeforeCall
hook into ctx.meta
which will be serialized.
I am implementing
passport-local
authentication in my user-service micro service. Since all examples for Passport assume tight coupling with express, I am having a tough time implementing thelogin
functionality.Specifically, Passport makes its
logIn
method available on thereq
object. Now this object is an express wrapper around the node.jsrequest
I don't know how to make these available in my actions.Usually the examples assume an express server:
So far, I have this in my
api.service.js
and my service schema is:
I found enough documentation around to implement user registration. But how do I get the
req
,res
andnext
objects to be available in my service action?req.logIn
to login the user,res.status(200).json({info: 'logged in'})
res.status(401)