Authentication is the process of determining the identity of a user. Common ways of authenticating a user are by asking the user for secret credentials (username & password) or by a third-party authentication provider such as Facebook or Google login.
Authorization is a related concept, which means that once we have verified the identity of a user, we can then determine what that user is allowed to do. For example, a user may be authorized to view a product, but not to edit it.
The term auth is shorthand for both authentication and authorization.
Auth in Vendure applies to both administrators and customers. Authentication is controlled by the configured AuthenticationStrategies, and authorization is controlled by the configured Roles and Permissions.
Sessions belong to the API they were created for: a session created on the Shop API is refused on the Admin API.
Vendure's authentication and authorization system is built on three pillars:
For diagrams, code examples, and detailed explanations of each area, see the dedicated pages linked above.
By default, Vendure uses a username/email address and password to authenticate users, which is implemented by the NativeAuthenticationStrategy.
There is a login mutation available in both the Shop API and Admin API which allows a customer or administrator to authenticate using
native authentication:
See the Managing Sessions guide for how to manage authenticated sessions in your storefront/client applications.
Custom authentication strategies are set via the VendureConfig.authOptions object:
In the above example, we define the strategies available for authenticating in the Shop API and the Admin API. The NativeAuthenticationStrategy is the only one actually provided by Vendure out-of-the-box, and this is the default username/email + password strategy.
The other strategies would be custom-built (or provided by future npm packages) by creating classes that implement the AuthenticationStrategy interface.
A strategy which is registered on both APIs must not resolve a Shop API request to a User who is an administrator. Since v3.8.0, Vendure records the API each session was created for. The Admin API accepts a session only if it was created for the Admin API. Keep the strategies which can resolve administrators on adminAuthenticationStrategy only.
The check runs on the Admin API only. A REST route added by a plugin is not checked, because a REST request cannot say which API it belongs to. A REST route gated by an administrator permission therefore still accepts a session created on the Shop API. If you add such a route, check ctx.session?.apiType === 'admin' in the handler.
If you create sessions yourself, for example from a REST controller which completes an SSO callback, pass the API the caller authenticated against as the apiType argument of AuthService.authenticate(), AuthService.createAuthenticatedSessionForUser() or SessionService.createNewAuthenticatedSession(). The request context of a REST route has an apiType of custom, which is not accepted on the Admin API.
A context built outside the request-response cycle carries no request, and RequestContext.empty() hardcodes apiType: 'admin'. A context in a job queue worker carries no request either, because serialize() deliberately drops it. A session created from such a context records the Shop API. Pass apiType: 'admin' if the session must work on the Admin API.
An API key records the API it was created on. Rotating the key and recovering its session keep that value, so an Admin API key stays an Admin API key and a key created from the Shop API or from a REST route stays refused on the Admin API.
In your storefront, you need to integrate the Google sign-in button as described in "Integrating Google Sign-In into your web app". Successful authentication will result in a onSignIn function being called in your app. It will look something like this:
On the backend, you'll need to define an AuthenticationStrategy to take the authorization token provided by the
storefront in the authenticate mutation, and use it to get the necessary personal information on that user from
Google.
To do this you'll need to install the google-auth-library npm package as described in the "Authenticate with a backend server" guide.
The verified flag passed to createCustomerAndUser does more than mark the account as verified — it also controls account linking. If a User already exists with the same email address, Vendure links the new external authentication method to that existing account only when verified: true.
An AuthenticationStrategy must therefore set verified: true only when the external provider has proven that the authenticating user owns the email address — for example, Google's email_verified claim (as used above). Setting verified: true for an email the provider has not verified would allow an attacker to register a victim's email at the provider and have their external login bound to the victim's existing Vendure account — an account takeover.
Since Vendure v3.7.0, attempting to link an unverified external identity to a pre-existing account throws an UnverifiedExternalEmailError. Creating a brand-new account (no existing account shares the email) is unaffected.
This example assumes the use of the Facebook SDK for JavaScript in the storefront.
An implementation in React might look like this:
Here's an example of an AuthenticationStrategy intended to be used on the Admin API. The use-case is when the company has an existing identity server for employees, and you'd like your Vendure shop admins to be able to authenticate with their existing accounts.
This example uses Keycloak, a popular open-source identity management server. To get your own Keycloak server up and running in minutes, follow the Keycloak on Docker guide.
In this example, we'll assume the login page is hosted at http://intranet/login. We'll also assume that a "login to Vendure" button has been added to that page and that the page is using the Keycloak JavaScript adapter, which can be used to get the current user's authorization token:
We also need to tell the Admin UI application about the custom login URL, since we have no need for the default "username/password" login form. This can be done by setting the loginUrl property in the AdminUiConfig:
First we will need to be making an HTTP call to our Keycloak server to validate the token and get the user's details. We'll use the node-fetch library to make the HTTP call:
The strategy is very similar to the Google authentication example (they both use the OpenID Connect standard), so we'll not duplicate the explanatory comments here:
Architecture reviews, custom plugin work, migrations, ongoing support. Get a hand from the team that builds Vendure.
Talk to the team