What are the differences between local Basic and Digest strategy in passportjs - passport.js

I understand the difference between Passport.js' Basic and Digest authentication, but what is the difference between the local strategy and Basic or Digest? In all three, you enter a username and password. Is the Basic strategy a type of user & password authentication? Please clarify.

If I understand correctly, the differences between the Local, Basic and Digest strategies in Passport.js are subtle but important. Here's the rundown:
Local (passport-local)
Passport's local strategy is a simple username and password authentication scheme. It finds a given user's password from the username (or other identifier) and checks to see if they match. The main difference between the local strategy and the other two strategies is its use of persistent login sessions. This strategy should be used over SSL/TLS.
Basic (passport-http)
The Basic strategy implemented by Passport looks nearly identical to the local strategy, with one subtle difference. The basic strategy is to be used with API endpoints where the architecture is stateless. As a result, sessions are not required but can be used. This strategy should also use SSL/TLS. The session flag can be set like so:
app.get('/private', passport.authenticate('basic', { session: false }), function(req, res) {
res.json(req.user);
});
Digest (passport-http)
The digest strategy is subtly different than the other two strategies in that it uses a special challenge-response paradigm so as to avoid sending the password in cleartext. This strategy would be a good solution when SSL/TLS wouldn't be available.
This is a good article on Basic vs. Digest: How to Authenticate APIs
Note: All three strategies make session support optional. The two passport-http strategies allow you to set the session flag while the Passport docs say this, regarding the passport-local strategy:
Note that enabling session support is entirely optional, though it is recommended for most applications.

If you a using the Passport Local strategy:
- a session is established, so you don't have to send creds on each request;
- username and password are provided in "username" and "password" headers by default;
If you a using the Passport Basic/Digest strategies:
- a session is not used, so you must provide the credentials at every API call;
- username and password/hash are contained within "Authorization" header;

Related

is passport required when using JWT

Very basic question but probably I miss something very big in the big picture.
I cannot figure out whether passport.js is needed or not when using JWT auth. Most examples have it but I fail to see the need.
In my app, there is a /login route and once the user authenticates successfully ( local auth, I check user, a hash pair in the database) I create a token with user id in it, set an expiry, sign it and send it back as the cookie in the response. Then I check the req cookies, decrypt and if they contain user id and not expired, I consider the request authenticated. (also traffic is https only if it changes anything)
Am I doing something wrong here as I don't have passport etc. in the process?
No, JWT (RFC 7519) is a standard. passport.js is an implementation that uses JWT. It is not required.

Trade username and password for a token

I have a Node.js application that offers several different routes in front of MongoDB. I need to make sure that only authenticated requests can access these routes.
Ideally, I want to set it up so that a username and password comes in to the API, and in a response we give them back a token. I don't mind managing the tokens inside MongoDB myself, but I need to make sure that the token we give back can make authenticated requests. I don't want to force the user to send their credentials each time, just the token.
I've read for a few days about passport, and there's currently 307 strategies. Which strategy am I describing here?
Which strategy am I describing here?
You are describing a Local Strategy.
As per their description:
This module lets you authenticate using a username and password in your Node.js applications.
I don't want to force the user to send their credentials each time, just the token.
Passport auth strategies just provide various ways to authenticate (or in simple terms login) the user, not how to persist that login. Login persistence is usually done with user sessions.
One way you can solve this is to combine the local strategy with the express session middleware. Combination of the two allows for a fairly simple auth system that requires the user to login once and then persists the session.
In a typical web application, the credentials used to authenticate a user will only be transmitted during the login request. If authentication succeeds, a session will be established and maintained via a cookie set in the user's browser.
Each subsequent request will not contain credentials, but rather the unique cookie that identifies the session. In order to support login sessions, Passport will serialize and deserialize user instances to and from the session.
PassportJS docs give an example how to achieve this.
For this you should prefer generating JWT tokens for a the login and then using the token to always authenticate user actions.
Following steps are need to implement this style of token login system
generate token on login
verify when token supplied and use the decoded data to identify user
use should proper middleware in order to protect your api.
Here is a link you could follow:
https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens

Proper passport strategy for anonymous mobile application

I'm building an anonymous app like yik yak and wanted to ask what is the proper passport strategy to use to authenticate. I'm currently using the device's UUID. I looked at the local strategy and that requires a username, password and it's session based (i'm implementing token based so my api isn't left open).
That said, would I implement a passport-http basic strategy and disregard the password altogether and use just the UUID as authentication?
Please help! I'm not entirely sure how to approach this issue. I do know, however, that I don't want the user to login, ever.
Thanks!

How to use jti claim in a JWT

The JWT spec mentions a jti claim which allegedly can be used as a nonce to prevent replay attacks:
The "jti" (JWT ID) claim provides a unique identifier for the JWT. The identifier value MUST be assigned in a manner that ensures that there is a negligible probability that the same value will be accidentally assigned to a different data object; if the application uses multiple issuers, collisions MUST be prevented among values produced by different issuers as well. The "jti" claim can be used to prevent the JWT from being replayed. The "jti" value is a case-sensitive string. Use of this claim is OPTIONAL.
My question is, how would I go about implementing this? Do I need to store the previously used jtis and issue a new JWT with every request? If so, doesn't this defeat the purpose of JWTs? Why use a JWT instead of just storing a randomly-generated session ID in a database?
My REST API has a Mongo database and I'm not opposed to adding a Redis instance. Is there a better authentication option than JWT? I mainly just don't want to store passwords on the client which eliminates HTTP authentication as an option, however, as I'm getting deeper into this JWT stuff, I'm starting to feel as if a custom token implementation or different standard might better suit my needs. Are there any node/express packages for token based authentication that supports token revocation and rotating tokens?
Would appreciate any advice.
Indeed, storing all issued JWT IDs undermines the stateless nature of using JWTs. However, the purpose of JWT IDs is to be able to revoke previously-issued JWTs. This can most easily be achieved by blacklisting instead of whitelisting. If you've included the "exp" claim (you should), then you can eventually clean up blacklisted JWTs as they expire naturally. Of course you can implement other revocation options alongside (e.g. revoke all tokens of one client based on a combination of "iat" and "aud").
This is an old question, but I just worked on something similar. So I will share my thoughts here.
First of all, I agree that making database calls while validating JWT tokens undermines their primary advantage of being stateless.
None of the previous answers mention refresh tokens, but I believe they present a good trade-off between scalability and security.
In short, one can use regular auth tokens with a short expiration time (say, 15 minutes) and refresh tokens with long-lived access (say, 2 weeks). Whenever an auth token expires, the refresh token (stored more securely) is used to generate a new auth token without the user having to log in again.
The jti claim is best suited for refresh tokens. That gives you the ability to revoke access while minimizing the number of database calls made.
Let's say an average user session is 30 minutes. If you have a jti claim on regular auth tokens, then every API call is doing at least one extra database call to check if the token is not blacklisted. However, if you're only using a jti claim on refresh tokens, you will only make 2 database calls for authentication purposes during the course of a 30 minutes session (assuming each auth token expires after 15 minutes). That's a big difference.
Regarding implementation, you can use a randomly-generated UID and use it as your table's primary key. That guarantees the calls are as fast as possible. Moreover, you can add an expiration_time column with the same value as the exp claim. That way you can easily (batch) remove all the expired refresh tokens.
Why use a JWT instead of just storing a randomly-generated session ID in a database?
Or, if I may paraphrase, "why would you use a JWT refresh token rather than a random string saved on the database?"
I think you can do that, but using a JWT token has at least two advantages: (1) if the token is invalid or expired (when you decode it), you don't have to make any database calls at all. You just return a response with an error status code. (2) if you have a big system, you might be storing the "random strings" in different database tables based on some criteria (say, per client application [web vs mobile]). How would you know the table in which to look up the random string? With a JWT token, you can simply add a client_id claim. So, the ability to have information in the token is useful.
You can use express-jwt package
See express-jwt on GitHub or on NPM.
Express-jwt handles revoked tokens as described here: https://github.com/auth0/express-jwt#revoked-tokens
var jwt = require('express-jwt');
var data = require('./data');
var utilities = require('./utilities');
var isRevokedCallback = function(req, payload, done){
var issuer = payload.iss;
var tokenId = payload.jti;
data.getRevokedToken(issuer, tokenId, function(err, token){
if (err) { return done(err); }
return done(null, !!token);
});
};
app.get('/protected',
jwt({secret: shhhhhhared-secret,
isRevoked: isRevokedCallback}),
function(req, res) {
if (!req.user.admin) return res.send(401);
res.send(200);
});
You can also read part 4. How do we avoid adding overhead? from this oauth0 blog post.
While in most cases JWT tokens should be validated offline, there are cases in which it might make sense to validate online. Your application almost certainly exposes many types of actions, some of which are more risky (and probably less frequent) than others. These risky actions could sometimes benefit from online token validation, since by the time the token is validated, it might not be safe to use it anymore (as it might have been revoked, for instance, which is particularly visible for longer-lived JWTs - which in turn minimize the pressure on refreshes). Another thing is that you might have some sort of a risk engine solution, which can decide whether issuing a token have been a good decision or not.

SPA best practices for authentication and session management

When building SPA style applications using frameworks like Angular, Ember, React, etc. what do people believe to be some best practices for authentication and session management? I can think of a couple of ways of considering approaching the problem.
Treat it no differently than authentication with a regular web application assuming the API and and UI have the same origin domain.
This would likely involve having a session cookie, server side session storage and probably some session API endpoint that the authenticated web UI can hit to get current user information to help with personalization or possibly even determining roles/abilities on the client side. The server would still enforce rules protecting access to data of course, the UI would just use this information to customize the experience.
Treat it like any third-party client using a public API and authenticate with some sort of token system similar to OAuth. This token mechanism would used by the client UI to authenticate each and every request made to the server API.
I'm not really much of an expert here but #1 seems to be completely sufficient for the vast majority of cases, but I'd really like to hear some more experienced opinions.
This question has been addressed, in a slightly different form, at length, here:
RESTful Authentication
But this addresses it from the server-side. Let's look at this from the client-side. Before we do that, though, there's an important prelude:
Javascript Crypto is Hopeless
Matasano's article on this is famous, but the lessons contained therein are pretty important:
https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/
To summarize:
A man-in-the-middle attack can trivially replace your crypto code with <script> function hash_algorithm(password){ lol_nope_send_it_to_me_instead(password); }</script>
A man-in-the-middle attack is trivial against a page that serves any resource over a non-SSL connection.
Once you have SSL, you're using real crypto anyways.
And to add a corollary of my own:
A successful XSS attack can result in an attacker executing code on your client's browser, even if you're using SSL - so even if you've got every hatch battened down, your browser crypto can still fail if your attacker finds a way to execute any javascript code on someone else's browser.
This renders a lot of RESTful authentication schemes impossible or silly if you're intending to use a JavaScript client. Let's look!
HTTP Basic Auth
First and foremost, HTTP Basic Auth. The simplest of schemes: simply pass a name and password with every request.
This, of course, absolutely requires SSL, because you're passing a Base64 (reversibly) encoded name and password with every request. Anybody listening on the line could extract username and password trivially. Most of the "Basic Auth is insecure" arguments come from a place of "Basic Auth over HTTP" which is an awful idea.
The browser provides baked-in HTTP Basic Auth support, but it is ugly as sin and you probably shouldn't use it for your app. The alternative, though, is to stash username and password in JavaScript.
This is the most RESTful solution. The server requires no knowledge of state whatsoever and authenticates every individual interaction with the user. Some REST enthusiasts (mostly strawmen) insist that maintaining any sort of state is heresy and will froth at the mouth if you think of any other authentication method. There are theoretical benefits to this sort of standards-compliance - it's supported by Apache out of the box - you could store your objects as files in folders protected by .htaccess files if your heart desired!
The problem? You are caching on the client-side a username and password. This gives evil.ru a better crack at it - even the most basic of XSS vulnerabilities could result in the client beaming his username and password to an evil server. You could try to alleviate this risk by hashing and salting the password, but remember: JavaScript Crypto is Hopeless. You could alleviate this risk by leaving it up to the Browser's Basic Auth support, but.. ugly as sin, as mentioned earlier.
HTTP Digest Auth
Is Digest authentication possible with jQuery?
A more "secure" auth, this is a request/response hash challenge. Except JavaScript Crypto is Hopeless, so it only works over SSL and you still have to cache the username and password on the client side, making it more complicated than HTTP Basic Auth but no more secure.
Query Authentication with Additional Signature Parameters.
Another more "secure" auth, where you encrypt your parameters with nonce and timing data (to protect against repeat and timing attacks) and send the. One of the best examples of this is the OAuth 1.0 protocol, which is, as far as I know, a pretty stonking way to implement authentication on a REST server.
https://www.rfc-editor.org/rfc/rfc5849
Oh, but there aren't any OAuth 1.0 clients for JavaScript. Why?
JavaScript Crypto is Hopeless, remember. JavaScript can't participate in OAuth 1.0 without SSL, and you still have to store the client's username and password locally - which puts this in the same category as Digest Auth - it's more complicated than HTTP Basic Auth but it's no more secure.
Token
The user sends a username and password, and in exchange gets a token that can be used to authenticate requests.
This is marginally more secure than HTTP Basic Auth, because as soon as the username/password transaction is complete you can discard the sensitive data. It's also less RESTful, as tokens constitute "state" and make the server implementation more complicated.
SSL Still
The rub though, is that you still have to send that initial username and password to get a token. Sensitive information still touches your compromisable JavaScript.
To protect your user's credentials, you still need to keep attackers out of your JavaScript, and you still need to send a username and password over the wire. SSL Required.
Token Expiry
It's common to enforce token policies like "hey, when this token has been around too long, discard it and make the user authenticate again." or "I'm pretty sure that the only IP address allowed to use this token is XXX.XXX.XXX.XXX". Many of these policies are pretty good ideas.
Firesheeping
However, using a token Without SSL is still vulnerable to an attack called 'sidejacking': http://codebutler.github.io/firesheep/
The attacker doesn't get your user's credentials, but they can still pretend to be your user, which can be pretty bad.
tl;dr: Sending unencrypted tokens over the wire means that attackers can easily nab those tokens and pretend to be your user. FireSheep is a program that makes this very easy.
A Separate, More Secure Zone
The larger the application that you're running, the harder it is to absolutely ensure that they won't be able to inject some code that changes how you process sensitive data. Do you absolutely trust your CDN? Your advertisers? Your own code base?
Common for credit card details and less common for username and password - some implementers keep 'sensitive data entry' on a separate page from the rest of their application, a page that can be tightly controlled and locked down as best as possible, preferably one that is difficult to phish users with.
Cookie (just means Token)
It is possible (and common) to put the authentication token in a cookie. This doesn't change any of the properties of auth with the token, it's more of a convenience thing. All of the previous arguments still apply.
Session (still just means Token)
Session Auth is just Token authentication, but with a few differences that make it seem like a slightly different thing:
Users start with an unauthenticated token.
The backend maintains a 'state' object that is tied to a user's token.
The token is provided in a cookie.
The application environment abstracts the details away from you.
Aside from that, though, it's no different from Token Auth, really.
This wanders even further from a RESTful implementation - with state objects you're going further and further down the path of plain ol' RPC on a stateful server.
OAuth 2.0
OAuth 2.0 looks at the problem of "How does Software A give Software B access to User X's data without Software B having access to User X's login credentials."
The implementation is very much just a standard way for a user to get a token, and then for a third party service to go "yep, this user and this token match, and you can get some of their data from us now."
Fundamentally, though, OAuth 2.0 is just a token protocol. It exhibits the same properties as other token protocols - you still need SSL to protect those tokens - it just changes up how those tokens are generated.
There are two ways that OAuth 2.0 can help you:
Providing Authentication/Information to Others
Getting Authentication/Information from Others
But when it comes down to it, you're just... using tokens.
Back to your question
So, the question that you're asking is "should I store my token in a cookie and have my environment's automatic session management take care of the details, or should I store my token in Javascript and handle those details myself?"
And the answer is: do whatever makes you happy.
The thing about automatic session management, though, is that there's a lot of magic happening behind the scenes for you. Often it's nicer to be in control of those details yourself.
I am 21 so SSL is yes
The other answer is: Use https for everything or brigands will steal your users' passwords and tokens.
You can increase security in authentication process by using JWT (JSON Web Tokens) and SSL/HTTPS.
The Basic Auth / Session ID can be stolen via:
MITM attack (Man-In-The-Middle) - without SSL/HTTPS
An intruder gaining access to a user's computer
XSS
By using JWT you're encrypting the user's authentication details and storing in the client, and sending it along with every request to the API, where the server/API validates the token. It can't be decrypted/read without the private key (which the server/API stores secretly) Read update.
The new (more secure) flow would be:
Login
User logs in and sends login credentials to API (over SSL/HTTPS)
API receives login credentials
If valid:
Register a new session in the database Read update
Encrypt User ID, Session ID, IP address, timestamp, etc. in a JWT with a private key.
API sends the JWT token back to the client (over SSL/HTTPS)
Client receives the JWT token and stores in localStorage/cookie
Every request to API
User sends a HTTP request to API (over SSL/HTTPS) with the stored JWT token in the HTTP header
API reads HTTP header and decrypts JWT token with its private key
API validates the JWT token, matches the IP address from the HTTP request with the one in the JWT token and checks if session has expired
If valid:
Return response with requested content
If invalid:
Throw exception (403 / 401)
Flag intrusion in the system
Send a warning email to the user.
Updated 30.07.15:
JWT payload/claims can actually be read without the private key (secret) and it's not secure to store it in localStorage. I'm sorry about these false statements. However they seem to be working on a JWE standard (JSON Web Encryption).
I implemented this by storing claims (userID, exp) in a JWT, signed it with a private key (secret) the API/backend only knows about and stored it as a secure HttpOnly cookie on the client. That way it cannot be read via XSS and cannot be manipulated, otherwise the JWT fails signature verification. Also by using a secure HttpOnly cookie, you're making sure that the cookie is sent only via HTTP requests (not accessible to script) and only sent via secure connection (HTTPS).
Updated 17.07.16:
JWTs are by nature stateless. That means they invalidate/expire themselves. By adding the SessionID in the token's claims you're making it stateful, because its validity doesn't now only depend on signature verification and expiry date, it also depends on the session state on the server. However the upside is you can invalidate tokens/sessions easily, which you couldn't before with stateless JWTs.
I would go for the second, the token system.
Did you know about ember-auth or ember-simple-auth? They both use the token based system, like ember-simple-auth states:
A lightweight and unobtrusive library for implementing token based
authentication in Ember.js applications.
http://ember-simple-auth.simplabs.com
They have session management, and are easy to plug into existing projects too.
There is also an Ember App Kit example version of ember-simple-auth: Working example of ember-app-kit using ember-simple-auth for OAuth2 authentication.

Resources