0

I have a simple multi-page app written in vanilla JS, Pug, and Node, that uses login with JWT. When a user signs in, the client is returned a JWT. The JWT is stored in localStorage. Here is my clientside ajax request for when a user logs in and is returned a token:

$.ajax({
    url: "/login",
    type: "POST",
    data: { arr },
    success: (res) => {
      if (res.status == 200) {
        localStorage.setItem("token", res.token);
        console.log("success");
      }
    },
    error: (err) => { console.log(err) }
  });

The above works fine.

Each page on the site has a number of different links or buttons: /home, /profile, /about, etc. Some of the routes are protected (only for logged in users), which is why I'm using JWT in the first place. I've seen on YouTube tutorials that the JWT should be stored in localStorage and sent in requests in the header. I believe I already have serverside middleware that will successfully check if a valid JWT is in the header. My question is this: How do I add the JWT to the request header when a user clicks a link on my page, so I can then do the verification serverside? Is this possible given that I'm using vanilla JS or do I need a different solution?

Here is a typical page for my site (written in Pug).

body
    h1 History of changes
    div View previous changes
    br
    each val, ind in histArr
      div.history
        a(href="/diff/" + val.numb)
          button See changes
        span= " " + val.date + " " + val.author + " " + val.message
      br

    a(href="/history")
      button /history
    a(href="/")
      button home
    a(href="/profile")
      button profile

How do I add the JWT to the header for when a user clicks on these buttons?

EDIT

For example: A user is on my site's home page. They click on a link that is a protected route. I want to check if they are logged in (i.e., have a JWT) before rendering the page. How do I add the JWT to the request header to check that? More specifically, is using an ajax call the only way to add my JWT to the request header or is there another way?

Scott
  • 639
  • 7
  • 18
  • Possible duplicate of [Use basic authentication with jQuery and Ajax](https://stackoverflow.com/questions/5507234/use-basic-authentication-with-jquery-and-ajax) – Suresh Prajapati Nov 12 '18 at 07:17

2 Answers2

2

Pass header from Ajax in this way ...

$.ajax({
 type: "POST",
 beforeSend: function(request) {
   request.setRequestHeader("token", {{{token}}); // Set dynamic token 
 },
 url: "/login",
 ... 
});

Another way :

$.ajax({
  url: 'YourRestEndPoint',
  headers: {
    'Authorization': {{token}},
    'Content-Type':'application/json'
  },
  method: 'POST',
  dataType: 'json',
  data: YourData,
  success: function(data){
    console.log('succes: '+data);
  }
});

View this link

update

Please check this link to pass header in vanilla js.

var httpHandler = function (err, str, contentType) {
  if (err) {
    res.writeHead(500, {'Content-Type': 'text/plain'});
    res.end('An error has occured: ' + err.message);
  } else {
    res.writeHead(200, {'Content-Type': contentType});
    res.end(str);
  }
};

Now you can try to set near at writeHear.

Sachin Shah
  • 3,826
  • 2
  • 12
  • 36
  • So I need every link to make an ajax request if I want to include the token? I can't just have a simple PROFILE link any more? – Scott Nov 12 '18 at 07:25
  • @Scott I didn't get you. :( – Sachin Shah Nov 12 '18 at 07:31
  • If a user is on my site's home page and wants to view their profile, they can click on a link that says "PROFILE." But I want to check if they're logged in before I render their profile. Only if they are logged in, they can go to their profile page. Thus, I want to check if they have a valid JWT when they click the PROFILE link. I have to do this via an ajax request now to set the header? Can't just use a simple link any more? – Scott Nov 12 '18 at 07:48
  • @Scott You can check user is logged in or not , then you can checked based on token and in a matter of link and other stuff , It's up to you that how you manage – Sachin Shah Nov 12 '18 at 07:50
  • Basically what I think I've come to figure out is this solution only works with a framework like React (maybe Angular, maybe others, I've only worked with React), since you can pass the JWT token to the server with those frameworks and render a view, whereas with Vanilla JS (using ajax) you can't do that and still protect your routes. So since I'm using Vanilla JS I need another solution such as cookies. – Scott Nov 21 '18 at 00:23
  • In one sense your answer is correct. If I wanted to add information to the request header, I use your method. But there's a bigger problem which is that JWT does not work for my purposes. JWT as an authentication method, I think, only really works with frameworks like React (possibly Angular as well). So I am currently trying to incorporate cookies as an authentication method in my app. I'll probably submit my own answer when I'm done as that is, I think, ultimately the way to do authentication with Vanilla JS. – Scott Nov 30 '18 at 04:41
0

You can set headers like this:

$.ajax({
  url: 'ajax_url',
  ...
  headers: {
    'Authorization': 'Bearer ' + 'your_token'
  }
})
Cong Nguyen
  • 1,880
  • 1
  • 16
  • 15
  • So do I need to do an ajax call for every protected route on my website now? For example, if a user is on my site's home page and wants to view their profile, they can click a link that says "PROFILE", but I want to check to make sure they are signed in (i.e., have a valid JWT) before I render their profile page. So every protected route now needs an ajax request to set the header? I can't set the header separately and still have a simple PROFILE link on my page? – Scott Nov 12 '18 at 07:46
  • I guess you have to use middleware in this case to send token every request. I don't know to write it in Vanilla but with Vuejs or ReactJs we need do that. – Cong Nguyen Nov 12 '18 at 07:53