Currently building a Single-page App with Node, with user authentication using passport and mongodb. I want to be able to send the user messages like "that username is already taken" or "please fill out all fields" on signup and login. However, all of the examples of this I have seen use a templating engine with a package like flash to render html based on javascript sent from the server. Is there a way around this? My app is pretty far along, and switching to a templating service is going to be a real pain. I don't need to render html, a simple alert box will suffice.
You can create controller action that matches the route and manually pass found model to the view.
In UserController:
find: function(req, res) {
User.findOne({'id': req.params['id']}, function(err, user) {
res.view({user: user})
})
}
Then You can reference this model in views/user/find.ejs:
<%- user.id %>
<%- user.name %>
use the above syntax to give alert();
I hope this is what you are looking for!
Related
I have a simple node express web app with passport JWT auth created. I use ejs for templates. Now I'm stuck.
I try to detect if User is Logged in or not. When Logged the User-Menu-dropdown on top right should be shown, otherwise a Login button. In the User-Menu-dropdown, the Email of the User should also be shown.
This is my setup:
Routes:
/user/* <-- From here all request will be authenticated using passport
/ <-- this are public sites
Code:
To detect if user are logged in, i use this ejs code:
<% if(email) { %>
<%- include('../header/userMenu', {email: email}); %>
<% } else { %>
<%- include('../header/loginButton'); %>
I use the {email: email} to pass the email porperty. This is came from the Site-Controllers, e.g. /user/dashboard where i define this like
res.locals.email = req.user.email
Now, i am a logged in user, and go to site /user/dashboard. In the top right, the User-Menu-dropdown are shown correctly, also the Email.
But, when i go to /help, the top Menu are shown BUT not the email address. After debug: In the Site-Controller help, the email are undefined.
I think, the problem is because the Routes in / are not authenticated through passport. Because of the JWT Authentication, i need tho verify the also the not-authenticated routes.
Also, I don't want to define the email property on every Controller.
How do I solve this problem?
I've been trying to figure out a better way to push a variable from the backend to the frontend. Right now I do something like this.
I have a MVC-pattern, so when hitting the route
app.get('/fil', middleWare.isLoggedIn, user.fil)
... trough node does some querying the DB, and pass on the data.
exports.fil = async (req, res) => {
try {
faktura = await Lan.find().populate('client', 'namn kundnr')
res.status(200).render('pages/createInvoice', {
faktura: faktura
});
} catch (err) {
return res.status(500).send({
message: err.message || "Some error occurred while retrieving datas."
});
};
};
... it generates the page, with the help of EJS (i love EJS) and then pass it on to the client/user.
And in the .ejs-file that is served to the client/user I add the following
<script>
var fakturor = <%- JSON.stringify(faktura) %>;
</script>
which then means that I use up the variable and work with it with JS.
And this is where my question pops up. Is this a good way to do it or is there any other way to handle it?
I guess one idea is to let the user to query the DB straight from the page, but in my case I believe it wouldn't actually be better for the user to do so (the user will reieve like 100 different rows that they will be able to filter and then download a file of)
But is there any other ways I could do this without the script-tag? Like i said, I guess a ajax-call from JS/the client could be used but could you do it any other way? Can EJS do it any other way?
ejs is used for static pages mainly, if you want to build a dynamic page I would look for a single page application framework like angular and react.
if you still want to use ejs you can use ajax call to the server to load a variable from the DB.
I would never query directly from Front end to DB because then you are not controlling the security of the server, always go through the BE.
also try to think if you really need a variable in the front end, can you solve your problem using rendering only?
I apologize if the question is not too clear.
As a background, I am working with ExpressJS and MongoDB (with mongoose etc). Also, I am a bit familiar with the topic, but I would like to do this the right way. I also use Handlebars as a view engine.
What I am trying to get at is, how do make it so that the server knows that a user is logged in and sends the right page, navigation bar, and other things?
I worked on a hackathon where I did something like this. Basically, it worked like this. When a user created an account, their informations were saved in a database. Inside the index js, I would check if the password and all matched (they were encrypted with Passport), then it they do, send the page with a parameter logged = true. If they weren't logged in, I would send the page with logged = false. Here's an example for logged out:
router.get('/', function(req, res, next) {
res.render('index', {title:'randomtitle', logged=false});
});
An example for logged in:
router.get('/', function(req, res, next) {
// code checks for cookies. Results shows that user exists. So we send this. we also find the username saved in the variable "someuser"
res.render('index', {title:'randomtitle', logged=true, username: someuser});
});
Then, the handlebars page will check if the user is logged in. For example:
<body>
{{if logged}}
<li> Hello {{username}}! </li>
{{else}}
<li> LOGIN </li>
{{/if}}
</body>
Hopefully, that makes sense. But I think that's a very sketchy approach of doing this! How do professional websites do it? Is there somewhere I can find examples for this?
Also, when I create initialize a server with express for example, it creates 2 routes automatically: index.js and user.js. What is the user.js for?
If anyone knows how it works in general (not specific to Node or Express), also please let me know.
A lot of people use passportjs.org for authentication in express. You have a lot of work to do. basically you can save user info from frontend form (html) to the database with get and post requests then add user info to session. This way at your routes you know who is authenticated. You could send the session to the front end template.
you could check to see if the user object is in the session and if it is that means they are logged in.
passportjs helps out with this a lot.
you could do req.session.logged = true
I am looking for a very simple example for using Passportjs (Local api) in my MEAN application. I took a reference from one example on github. There they have used jade to render the page after authentication. But I just want to use my home.html to show home page after authentication.
I have searched many example but in all they are using either jade or ejs. I don't want to use any engine to render the home page.
If anyone can provide a very simple example just using MEAN that would be a great help.
I don't want to use jade or ejs. Just simple html to render page.
Just setup a route similar to this:
app.route("/login")
.post(passport.authenticate("local"), function (req, res) {
res.json(req.user);
});
Then call that as an post call from the function you bind the form to in angular, you don't need to use jade/pug/ejs or any of it. You can simply use express as an API server. Just have angular redirect to the route you want after the successful return of the authentication (you should get a user object back)
I'm making a basic web app with Node.js and Express 4 and I'm trying to implement a "follow" function. I did some inspecting on the Github website and noticed it used a form with a follow button that would post to the server to follow a user. I think this sounds like a good approach but when I post I don't want to have to reload the page just like the github website.
How does one this inside of Express 4? Everything I put inside the .post route always end up in a page load. I'm pretty sure in jQuery's ajax method you can just return false and nothing will happen to the page, just the request will be sent which is what I want to happen because I'm using a RESTful api and I want to add the user to the current user's following but I don't want to have to use jQuery just for this function. I would prefer it be done in Express if possible, though any help would be appreciated.
views/user.handlebars
<h1>{{user.displayName}}</h1>
<p>#{{user.username}}</p>
<form action="" data-userid="{{user._id}}" method="post">
<button name="follow" type="submit">Follow</button>
</form>
routes/users.js
app.route('/:username')
.get(function(req, res) {
// get :username user from api and load info
...
})
.post(function(req, res) {
// don't reload page
???
// send PUT :username user to current users following array
...
});
So you're on the right track, but instead of putting your actions in the HTML (in your jade file) you're gonna have to add a script section to your jade and use javascript to attach an onClick event to the button so that when you press the button you invoke your ajax method.
Let me know if that doesn't make sense.