Add InstantSearch and Autocomplete to your search experience in just 5 minutes
A good starting point for building a comprehensive search experience is a straightforward app template. When crafting your application’s ...
Senior Product Manager
A good starting point for building a comprehensive search experience is a straightforward app template. When crafting your application’s ...
Senior Product Manager
The inviting ecommerce website template that balances bright colors with plenty of white space. The stylized fonts for the headers ...
Search and Discovery writer
Imagine an online shopping experience designed to reflect your unique consumer needs and preferences — a digital world shaped completely around ...
Senior Digital Marketing Manager, SEO
Winter is here for those in the northern hemisphere, with thoughts drifting toward cozy blankets and mulled wine. But before ...
Sr. Developer Relations Engineer
What if there were a way to persuade shoppers who find your ecommerce site, ultimately making it to a product ...
Senior Digital Marketing Manager, SEO
This year a bunch of our engineers from our Sydney office attended GopherCon AU at University of Technology, Sydney, in ...
David Howden &
James Kozianski
Second only to personalization, conversational commerce has been a hot topic of conversation (pun intended) amongst retailers for the better ...
Principal, Klein4Retail
Algolia’s Recommend complements site search and discovery. As customers browse or search your site, dynamic recommendations encourage customers to ...
Frontend Engineer
Winter is coming, along with a bunch of houseguests. You want to replace your battered old sofa — after all, the ...
Search and Discovery writer
Search is a very complex problem Search is a complex problem that is hard to customize to a particular use ...
Co-founder & former CTO at Algolia
2%. That’s the average conversion rate for an online store. Unless you’re performing at Amazon’s promoted products ...
Senior Digital Marketing Manager, SEO
What’s a vector database? And how different is it than a regular-old traditional relational database? If you’re ...
Search and Discovery writer
How do you measure the success of a new feature? How do you test the impact? There are different ways ...
Senior Software Engineer
Algolia's advanced search capabilities pair seamlessly with iOS or Android Apps when using FlutterFlow. App development and search design ...
Sr. Developer Relations Engineer
In the midst of the Black Friday shopping frenzy, Algolia soared to new heights, setting new records and delivering an ...
Chief Executive Officer and Board Member at Algolia
When was your last online shopping trip, and how did it go? For consumers, it’s becoming arguably tougher to ...
Senior Digital Marketing Manager, SEO
Have you put your blood, sweat, and tears into perfecting your online store, only to see your conversion rates stuck ...
Senior Digital Marketing Manager, SEO
“Hello, how can I help you today?” This has to be the most tired, but nevertheless tried-and-true ...
Search and Discovery writer
As you build your own APIs, examining your use cases will help you decide which security methods to implement for each API. For some use cases, API keys are sufficient; in others, you’ll want the additional protection and flexibility that comes with JSON Web Tokens (JWT) authorization. So in the comparison API keys versus JWT authorizations, the winner is .. it depends.
All API calls require some measure of security and access control. API keys with a sensible ACL can provide enough security without adding too much overhead. But with the increased use of microservices for nearly every small and large task, your API ecosystem may need a more unified, granular, and secure method like JWT authorization.
Online businesses that use a cloud-based Search API can normally expose read-only API keys without great risk – if the underlying index of data contains no secrets. In fact, client-side apps should connect to the cloud search engine directly for performance reasons – thereby exposing their API key – to avoid the lengthier trip to the back-end server before going to the cloud. On the other hand, index updates require restricted access API keys, which should never be exposed.
But in both use cases (search and indexing), API keys are generally fine; there’s no urgent need for the overhead of JWT authorization.
Increasingly, however, APIs demand more flexibility and protection. JWT authorization not only adds an additional level of security (more about this below), it also provides a more manageable and easier method to orchestrate the multitude and network of APIs used on a daily basis. As described in the next sections, JWT centralizes authentication & authorization by generating a single shared token that contains user and app-level information (encrypted or hashed) to help any API in the same ecosystem determine what the token-holder is allowed to do.
API keys, at first glance, seem so simple – you just need to send the proper API key and you’re ready to go. But that’s a bit deceptive. When your ecosystem relies on many integrated microservices, managing numerous API keys becomes messy, unreliable, and nearly impossible to manage. They grow in number, they change, they expire, they get deleted, their ACLs change – all that and more, without notifying the apps and users relying on these same API keys.
With JWT, you lay the foundation for a single sign-on architecture. We discuss this below in the section Switching over to JWT.
Related Links –
- Dig into API key security.
- For CLI people, an all new Algolia CLI tool.
- All about security and compliance at Algolia.
API keys are direct, simple, and fully transparent. They don’t represent any underlying information, they do not encrypt a secret message. They are simply an unreadable unique id.
Here’s an example of a publicly available API key in client-side javascript. The code includes an App ID (`app-id-BBRSSHR`) that uses the API key (`temp-search-key-ere452sdaz56qsjh565d`) to allow it to search. The App ID refers to one of your user-facing apps (like an online website or streaming service). The API key is temporary and short-lived (expiring after some period of time) to provide some protection from unwanted use or abuse.
import { hitTemplate } from "./helpers"; const search = instantsearch({ appId: "app-id-BBRSSHR", apiKey: "temp-search-key-ere452sdaz56qsjh565d", indexName: "demo_ecommerce" });
Another example: Indexing, which requires a more secure API key. It has the same format (appId
+ apiKey
), but it is private because it is hidden from the public, either in compiled code or a secure database on your back end. The App ID (YourApplicationID
) refers to the back office system. The API key (YourAdminAPIKey
) might be a permanent admin key that changes only once a year for simpler maintenance.
use Algolia\AlgoliaSearch\SearchClient; $client = SearchClient::create( 'YourApplicationID', 'YourAdminAPIKey' ); $index = $client->initIndex('demo_ecommerce'); $index->saveObject( [ 'firstname' => 'Jimmie', 'lastname' => 'Barninger', 'city' => 'New York', 'objectID' => 'myID' ] );
A JWT token is a large unreadable set of characters that contains hidden and encoded information, masked by a signature or encryption algorithm. It’s made up of three parts: a header, body, and signature. They are separated by a period: Header.Body.Signature
.
EZPZAAdsqfqfzeezarEUARLEA.sqfdqsTIYfddhtreujhgGSFJ.fkdlsqEgfdsgkerGAFSLEvdslmgIegeVDEzefsqd
The JWT header is EZPZAAdsqfqfzeezarEUARLEA
, which contains the following information:
{ "alg": "HS256", "typ": "JWT" } { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
There are different algorithms available, for example RS256
and HS256
. Here we use HS256
which requires a private key to be used when generating the signature. `RS256` uses both a private and a public key combination.
The JWT body (called the payload) is sqfdqsTIYfddhtreujhgGSFJ
, which contains the user’s identity to help establish the token user’s rights. It also gives other information, such as an expiration date (the shorter the more secure):
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
The signature is fkdlsqEgfdsgkerGAFSLEvdslmgIegeVDEzefsqd
, which is generated by combining the header, body, and a shared private key, using the HS256 hashing method, as indicated in the header.
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
And so that’s how you get the following token: Header.Body.Signature
:
EZPZAAdsqfqfzeezarEUARLEA.sqfdqsTIYfddhtreujhgGSFJ.fkdlsqEgfdsgkerGAFSLEvdslmgIegeVDEzefsqd
Both API key and JWT are used for authentication and authorization, but they do it differently.
API keys authenticate and authorize using the same API key. JWT Authorization requires an initial authentication process before it generates the authorization token. Once the token is generated, it is used across the ecosystem to determine what the token holder can and cannot do.
Additionally, API keys authenticate the application not the user; whereas, JWT authenticates both the user and the application. Of course, you could use API keys for user-level authorization, but it’s not well-designed for that – an ecosystem would need to generate and manage API keys for every user or session id, which is unnecessarily burdensome for a system.
In terms of security, both API keys and JWT are open to attacks. The best security measure is to implement a secure architecture for all end-to-end communications.
That said, API keys are historically less secure because they rely on being hidden. You can hide keys with SSL/TLS/HTTPS, or by restricting their usage to back-end processes. However, you can’t control all API use; API keys are likely to leak; HTTPS is not always possible; and so on. With JWT, because the token is hashed / encrypted, it comes with a more secure methodology that is less likely to be exposed.
The most notable difference between an API key and a JWT token is that JWT tokens are self-contained: they contain information an API needs to secure the transaction and determine the granularity of the token-holder’s rights. In contrast, API keys use their uniqueness to gain initial access; but then the API needs to find a key’s associated ACL in a central table to determine exactly what the key gives access to. Typically, the API key provides only application-level security, giving every user the same access; whereas the JWT token provides user-level access.
A JWT token can contain information like its expiration date and a user identifier to determine the rights of the user across the entire ecosystem.
Let’s take a look at some of the information you can include in a JWT token:
iss (issuer): identifies the principal that issued the JWT. sub (subject): identifies the principal that is the subject of the JWT. Must be unique aud (audience): identifies the recipients that the JWT is intended for (array of strings/uri) exp (expiration time): identifies the expiration time (UTC Unix) after which you must no longer accept this token. It should be after the issued-at time. nbf(not before): identifies the UTC Unix time before which the JWT must not be accepted iat (issued at): identifies the UTC Unix time at which the JWT was issued jti (JWT ID): provides a unique identifier for the JWT.
Example
{ "iss": "stackoverflow", "sub": "joe", "aud": ["all"], "iat": 1300819370, "exp": 1300819380, "jti": "3F2504E0-4F89-11D3-9A0C-0305E82C3301", "context": { "user": { "key": "joe", "displayName": "Joe Smith" }, "roles":["admin","finaluser"] } }
So here’s the scenario. You have many applications:
The problem arises when there are more APIs running the show. Where do you store the 100s+ of API keys needed for all this access? Managing too many API keys requires a table of API keys to be made available to all apps that run within the ecosystem.
Thus, every app in the ecosystem would have to be aware of the database. Each app would need to connect and read from that table. And some apps would be allowed to generate new keys or modify existing keys. All of which is fine, but becomes difficult to maintain. One way to manage this is to create an API that validates a key against this database. But for that, you’ll need a second authentication system to connect to this API.
Not only is retrieving the API keys cumbersome, but maintaining their duration and level of authorization becomes tedious. And not every app functions at the app level, they need user-level rights. Additionally, APIs can be used in ways that differ from system to system. Worse, different apps share API keys, and are therefore dependent on the different apps to maintain correct access-levels of the shared API keys.
Any API that requires authentication can easily switch over to JWT’s authorization. With JWT authorization, you get a user-based authentication. Once the user is authenticated, the user gets a secure token that they can use on all systems. The management of the user (and therefore the token) is centralized. You set up access rights and you give each user different rights for each system. The JWT authorization endpoint authenticates the user and creates the token.
With that architecture, the next step is to create a single sign on into the full ecosystem and rely only on the token for rights. In the end, the simplest and most robust and manageable approach is to create this single endpoint dedicated to do both authentication & authorization, such that all other servers across the entire ecosystem can rely on that central point to authorize the API interactions between client and server.
As an application developer, my primary concern when building APIs is that they are used properly and provide the correct data and functionality. I therefore rely heavily on the advice of DevOps to suggest the best and most manageable security. But it’s not just about security. In a large ecosystem, we need a simple and robust way to access microservices across multiple systems and servers, which is best served by centralizing the authentication and authorization processes.
Third-party APIs should be easy to use and fast to implement, with little upfront work when integrating. Additionally, you need to share the key used to sign the token. So it’s best when you control both ends, which is unlikely in third-party sceneries. You also need to trust the implementation. for example an API could choose to ignore the expiration date or the NBF (“not before”).
You’ll want to use JWT when multiple services need to communicate with each other over a vast network. Centralizing and securing those exchanges is crucial. It’s especially important when each network or app requires different levels of access based on the user, not just the app. It’s also important to have control over the traffic and to be able to prioritize network calls. Finally, you want the simple plug-and-play experience when adding new microservices or improving existing ones.
Related Links –
- Dig into API key security.
- For CLI people, an all new Algolia CLI tool.
- All about security and compliance at Algolia.
Powered by Algolia Recommend