0

I am currently trying to pass my password reset generated token inside my unprotected route but whenever I execute my GET request, I receive an 401 Unauthorized request.

I've tried including the package Path-to-RegExp and constructing a separate array route but it didn't work:

let tokens = [];
const unprotected = [
  pathToRegexp('/user/reset/:token', tokens),
];

My password-reset token is generated in a separated service and called in a controller:

 const token = crypto.randomBytes(20).toString('hex');
          user.update({
            resetPasswordToken: token,
            resetPasswordExpires: Date.now() + 360000,
          });

Here is how I've structured my expressJwt with unless:

app.use(expressJwt({
  secret: process.env.SECRET_BEARER,
  getToken: req => {

     MY TOKEN AUTHORISATION CODE IS PLACED HERE.
 }

}).unless({ path: ['/images/', '/user/password-reset', unprotected ]}));

My issue is that whenever I try to create a unauthenticated route such as .unless({path: ['/images/', '/user/password-reset', '/user/reset/:token' ]})); the route /user/reset/:token is only parsed as a string a the value of :token is not actually passed.

I've read some similar questions about passing it with regex or functions but I couldn't figure it out myself. This and this question have been particularly useful on how to approach the problem.

2 Answers2

1

You can pass a regex to unless, which you may have already realized since you tried to use Path-to-RegExp. You could also just try to write the regex yourself and pass it directly to unless. In your case your unless would look like this:

.unless({ path: [/\/images\//, /\/user\/password-reset\//, /^\/user\/reset\/[a-z0-9_-]*/]}));

EDIT: this SO answer suggest that you cannot combine regex and strings in the same array, so I've converted all paths to regex expressions.

etarhan
  • 4,138
  • 2
  • 15
  • 29
  • It returns a `404` now for some reason, I don't think that this is matching properly. – someonewithakeyboardz1 Apr 11 '19 at 15:27
  • @someonewithakeyboard what is the exact path that you are requesting? – etarhan Apr 11 '19 at 15:28
  • I need to pass `/user/reset/:token` where `:token` is the value of my password reset token.. – someonewithakeyboardz1 Apr 11 '19 at 15:29
  • @someonewithakeyboard is the token alphanumeric with possible dashes and underscores? If so see my updated answer – etarhan Apr 11 '19 at 15:34
  • yeah I've tried this but I keep receiving `404` on my get which points to `"http://localhost:3003/user/reset/" + tokenURL` – someonewithakeyboardz1 Apr 11 '19 at 15:41
  • @someonewithakeyboard are you sure that tokenUrl is just the token and not accidentally an actual url (as the name suggests)? Could you console.log this tokenUrl? – etarhan Apr 11 '19 at 15:44
  • `eae81f8ac64bd3e08c4ae7663419f1325519b624` whenever I console log the token. I'm sure it is because I'm passing it through a generated email and then passing the the token as props to my url. – someonewithakeyboardz1 Apr 11 '19 at 15:46
  • I'm still getting a `404` for some reason. I think that when I switch all the paths to regex, it doesn't detect anything at all. It just returns a `404` for all paths. I'll look into this issue in more details, thanks for the support so far.. – someonewithakeyboardz1 Apr 11 '19 at 16:10
0

You have an array within an array for the value of path passed into unless.

Change:

}).unless({ path: ['/images/', '/user/password-reset', unprotected ]}));

To:

}).unless({ path: unprotected }));

And change unprotected to include the other paths:

const unprotected = [
  '/images/',
  '/user/password-reset',
  pathToRegexp('/user/reset/:token', tokens),
];

Ensure you test with a path that includes a token e.g: /user/reset/123-some-real-looking-value

Dean Taylor
  • 40,514
  • 3
  • 31
  • 50