diff --git a/.optimize-cache.json b/.optimize-cache.json index 828a3aaef7..779bfe19a5 100644 --- a/.optimize-cache.json +++ b/.optimize-cache.json @@ -914,6 +914,7 @@ "static/images/blog/nuxt-starter-sites/deployment-logs.png": "cfda32328bf663dc9dac32c503730d0790aeeb35190dd201947ce18f59bd026d", "static/images/blog/nuxt-starter-sites/template.png": "c881577b5a1b1edb32aa08a42afc0ba3cd1fe084a64c347b1dd6618312b56c44", "static/images/blog/oauth-openid.png": "5228f7be3e0acd3d5c3f3f0ab4d2589a2cd6aea43508cecd9624c777f97fa909", + "static/images/blog/oauth-server-vs-oauth-client-what-is-the-difference/cover.png": "f36ec99ee1dacee39136973f8d8dbd7ada00678687b86467f8785da06314b821", "static/images/blog/offline-first-journal/cover.png": "be142679d30a9144f0623b78dfa2810048b46c5cbdea83d0e2d7f36d61233c5d", "static/images/blog/offline-first-journal/demo.png": "55e48ac98bc1d8f9add353b034c22c17cc158d951a31e7df4cb23a2e3d7efaf2", "static/images/blog/open-source-baas-alternatives/cover.png": "1ca9d44ab5faf6199fe782c5c833cd75d54acc7ad5cb18f46dea06b62abec5c4", @@ -1277,6 +1278,7 @@ "static/images/blog/what-is-mcp/claude-mcp-chat.png": "26842cfebca3ec2cec89448e1c0d7ddb3f5421cc57acdb8780d48d30a54cad82", "static/images/blog/what-is-mcp/claude-mcp-tools.png": "3a5ae700867b8671b5c9e3af61b094aeb64611168463db66ff440e0d427ac6bc", "static/images/blog/what-is-mcp/cover.png": "dc4537990c91d6f1768c5ab8775e5c52239eb901b15e2e74fce8b5a018855c32", + "static/images/blog/what-is-oauth-a-beginners-guide/cover.png": "87814de2f0eed9a6e5231d62a26ae1295d13580911bd5f88e9cd9b41732fb7cd", "static/images/blog/what-is-redis-a-complete-guide-for-developers/cover.png": "b7b87a372bbb99421c2ab6df37430da960728b5cf339f1803c432644154c764f", "static/images/blog/what-is-serverless-an-expert-guide-for-developers/cover.png": "fd88e32613ca877625cd69e0e38ba76c3c2cc73da05b789739928712bdd7b454", "static/images/blog/when-custom-backend-stops-being-worth-it/cover.png": "d03b13c4e8f3294823a7883cdae89ca18a4030b170c51f597bd139c9ca274793", diff --git a/src/routes/blog/post/oauth-server-vs-oauth-client-what-is-the-difference/+page.markdoc b/src/routes/blog/post/oauth-server-vs-oauth-client-what-is-the-difference/+page.markdoc new file mode 100644 index 0000000000..044fc80bf4 --- /dev/null +++ b/src/routes/blog/post/oauth-server-vs-oauth-client-what-is-the-difference/+page.markdoc @@ -0,0 +1,145 @@ +--- +layout: post +title: "OAuth server vs. OAuth client: What is the difference?" +description: Learn the difference between an OAuth server and OAuth client, how each works, and the role they play in secure authorization flows. +date: 2026-07-21 +cover: /images/blog/oauth-server-vs-oauth-client-what-is-the-difference/cover.avif +timeToRead: 5 +author: aishwari +category: comparisons +featured: false +unlisted: true +faqs: + - question: What is the difference between an OAuth server and an OAuth client? + answer: An OAuth server authenticates users, collects consent, and issues access tokens. An OAuth client requests those tokens and uses them to access a protected API on the user’s behalf. + - question: Is an OAuth server the same as an authorization server? + answer: Usually, yes. The precise OAuth term is authorization server. People often use OAuth server more broadly to describe the authorization server and the protected resource server operated by the same provider. + - question: What is the difference between an authorization server and a resource server? + answer: The authorization server authenticates users and issues tokens. The resource server hosts the protected API or data and accepts valid access tokens before returning a resource. + - question: What does an OAuth server do? + answer: An OAuth server verifies the user’s identity, displays the consent screen, processes authorization requests, and issues access and refresh tokens. It may also validate, revoke, and rotate tokens. +--- +"OAuth server" and "OAuth client" get used interchangeably in a lot of tutorials, and that is where the confusion starts. They are not two names for the same thing. They are two different roles on opposite ends of the same authorization flow, and mixing them up leads to real bugs: tokens stored in the wrong place, secrets leaked to the browser, or a login flow that never completes. + +If you are adding "Sign in with Google" to your app, integrating a third-party API, or building a service other apps authenticate against, you need to know which role you are playing. This post breaks down what an OAuth server is, what an OAuth client is, how they interact, and how to decide which side you are building. + +# OAuth server vs. OAuth client: the short answer + +An **OAuth server** issues and validates access tokens. It authenticates the user, asks for their consent, and hands out tokens that grant access to protected resources. Google, GitHub, and Microsoft all run OAuth servers. + +An **OAuth client** is the application that wants access. It requests tokens from the OAuth server and uses them to call an API on the user's behalf. Your web app, mobile app, or backend service is the OAuth client. + +Put simply: the client asks for access, and the server decides whether to grant it. If you are consuming someone else's login or API, you are building an OAuth client. If you are the one letting other apps authenticate against your service, you are running an OAuth server. + +# The four roles in OAuth 2.0 + +"Server" and "client" are shorthand. The [OAuth 2.0 specification](https://datatracker.ietf.org/doc/html/rfc6749) actually defines four roles, and understanding all four removes most of the ambiguity. + +* **Resource owner:** the user who owns the data and can grant access to it. When you let an app read your Google Calendar, you are the resource owner. +* **Client:** the application requesting access to the resource owner's data. This is the "OAuth client." +* **Authorization server:** the server that authenticates the resource owner and issues access tokens after consent. This is the core of the "OAuth server." +* **Resource server:** the API that holds the protected data and accepts access tokens to serve it. In practice, the authorization server and resource server are often run by the same provider, which is why people collapse them into one term: the OAuth server. + +So when someone says "OAuth server," they usually mean the authorization server plus the resource server operated by a provider like Google. When they say "OAuth client," they mean the app you are building. + +# What is an OAuth server? + +An OAuth server (the authorization server) is responsible for the trust in the whole system. Its job is to verify who the user is, confirm what they are agreeing to share, and issue tokens that prove that grant. + +A typical OAuth server handles: + +* **Authentication:** confirming the user's identity, usually through a login screen the client never sees. +* **Consent:** showing the user which permissions (scopes) the client is requesting and letting them approve or deny. +* **Token issuance:** generating access tokens, and often refresh tokens, scoped to what the user approved. +* **Token validation:** verifying tokens on incoming requests so the resource server can trust them. + +The key point is that the OAuth server owns the user's credentials. The password, the multi-factor prompt, the session, all of it lives on the server side. A client never sees the user's password, which is the entire reason OAuth exists. Instead of handing your Google password to a random app, you let Google's OAuth server authenticate you and issue a limited token. + +Running an OAuth server is a serious undertaking. You are responsible for securely storing credentials, implementing consent screens, managing token lifecycles, rotating signing keys, and defending against a long list of attacks. Most teams should not build one from scratch. + +# What is an OAuth client? + +An OAuth client is any application that wants to access protected resources on a user's behalf. It never handles the user's password. Instead, it redirects the user to the OAuth server, waits for an authorization code, exchanges that code for an access token, and then uses the token to call the API. + +The OAuth spec splits clients into two types, and the distinction matters for security. + +## Confidential clients + +A **confidential client** can keep a secret. This is a server-side application, like a backend written in Node.js or Python, where you can safely store a client secret that is never exposed to the user. Confidential clients use the client secret when exchanging the authorization code for a token, which proves the request came from the real app. + +## Public clients + +A **public client** cannot keep a secret. Single-page apps, mobile apps, and desktop apps fall into this category, because any secret shipped in their code can be extracted. Public clients rely on the [PKCE extension](https://oauth.net/2/pkce/) (Proof Key for Code Exchange) instead of a client secret to protect the token exchange. + +Getting this classification wrong is one of the most common OAuth mistakes. Embedding a client secret in a mobile app or browser bundle is the same category of error as putting an API key in client-side code: anyone who inspects the app can extract it. + +# How the OAuth server and client work together + +The two roles come together in the [authorization code flow](https://oauth.net/2/grant-types/authorization-code/), the most common OAuth 2.0 grant type. Here is the sequence, with the roles labeled: + +1. The **client** redirects the user to the **OAuth server's** authorization endpoint, passing its client ID, the requested scopes, and a redirect URL. +2. The **OAuth server** authenticates the user (login screen) and shows the consent prompt. +3. The user approves. The **OAuth server** redirects back to the client's redirect URL with a short-lived authorization code. +4. The **client** sends that code back to the **OAuth server's** token endpoint, along with its client secret (confidential) or PKCE verifier (public). +5. The **OAuth server** validates everything and returns an access token, and often a refresh token. +6. The **client** uses the access token to call the **resource server's** API on the user's behalf. + +Notice that the user's password only ever touches the OAuth server. The client only ever holds tokens, and only the tokens the user explicitly approved. That separation is the whole point of OAuth, and it is why the client and server roles are strictly divided. + +# Key differences between an OAuth server and OAuth client + +| Aspect | OAuth server | OAuth client | +| ----------------------- | --------------------------------------------------------- | ------------------------------------------------------------ | +| Primary job | Authenticate users, issue and validate tokens | Request tokens, call APIs on the user's behalf | +| Handles passwords | Yes, owns user credentials | No, never sees the user's password | +| Who runs it | Providers like Google, GitHub, Microsoft | Your app: web, mobile, or backend | +| Holds the client secret | Issues and verifies it | Stores it (confidential) or uses PKCE (public) | +| Security burden | Credential storage, consent, key rotation, attack defense | Safe token storage, correct client type, redirect validation | +| You build one when | Other apps need to authenticate against your service | You consume a provider's login or API | + +# Which one are you building? + +For the vast majority of apps, you are building an **OAuth client**. You want users to sign in with Google or GitHub, or you need to call an external API like Stripe or Slack on a user's behalf. In both cases your app is the client, and the provider runs the OAuth server. + +You only need to run an **OAuth server** if you are the provider: if other developers' applications need to let their users log in with your service, or if you expose an API that third parties access on behalf of your users. That is a much rarer requirement, and it comes with the full weight of securing user credentials. + +Most teams that think they need an OAuth server actually need a managed authentication layer. If you just want users to log in and stay logged in, what you want is a client integration plus session management, not a full authorization server of your own. + +# Where Appwrite fits into OAuth + +When you add social login to your app with [Appwrite Auth](/docs/products/auth), Appwrite acts as the OAuth client on your behalf. You do not build the redirect handling, the code exchange, or the token storage yourself. Appwrite handles the entire OAuth2 flow server-side across 30+ providers, so provider secrets stay off your frontend. + +The pattern looks like this: your app calls a single SDK method to start the flow, the user authenticates with the provider's OAuth server, and Appwrite exchanges the authorization code for tokens and creates a session for you. We cover the exact flow in [How Appwrite handles OAuth](/blog/post/appwrite-oauth). + +```js +import { Client, Account, OAuthProvider } from 'appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +const account = new Account(client); + +// Start the OAuth flow; Appwrite acts as the OAuth client for you +const authUrl = await account.createOAuth2Token({ + provider: OAuthProvider.Github, + success: 'https://yourapp.com/callback', + failure: 'https://yourapp.com/login?error=oauth' +}); + +window.location.href = authUrl; +``` + +Because Appwrite runs the token exchange on the server, your app stays a thin, secure OAuth client without you having to reason about confidential versus public client rules, PKCE, or refresh logic. If OAuth as a concept is still new to you, start with [What is OAuth? A beginner's guide](/blog/post/what-is-oauth-a-beginners-guide) before wiring up providers. + +# Getting started with Appwrite Auth + +The line between an OAuth server and an OAuth client is really a line of responsibility. The server owns identity and issues trust; the client consumes it. Almost every app you build sits on the client side, and the safest way to stay there is to let a managed layer handle the flow instead of rolling your own authorization server. + +Appwrite gives you social login, session management, and token handling out of the box, so you can ship OAuth without becoming an OAuth expert first. Configure a provider in the Console and you have working "Sign in with Google" in minutes. + +* [Appwrite Auth overview](/docs/products/auth) +* [OAuth2 providers documentation](/docs/products/auth/oauth2) +* [How Appwrite handles OAuth: Google, GitHub, and beyond](/blog/post/appwrite-oauth) +* [What is OAuth? A beginner's guide](/blog/post/what-is-oauth-a-beginners-guide) +* [Join the Appwrite Discord community](https://appwrite.io/discord) \ No newline at end of file diff --git a/src/routes/blog/post/what-is-oauth-a-beginners-guide/+page.markdoc b/src/routes/blog/post/what-is-oauth-a-beginners-guide/+page.markdoc new file mode 100644 index 0000000000..f430cf507b --- /dev/null +++ b/src/routes/blog/post/what-is-oauth-a-beginners-guide/+page.markdoc @@ -0,0 +1,166 @@ +--- +layout: post +title: "What is OAuth? A beginner's guide" +description: OAuth is an open standard that lets apps access user data from another application without sharing passwords. Learn how OAuth 2.0 works, its flows, and how to add it to your app. +date: 2026-07-21 +cover: /images/blog/what-is-oauth-a-beginners-guide/cover.avif +timeToRead: 5 +author: aishwari +category: security +featured: false +unlisted: true +faqs: + - question: What does OAuth stand for? + answer: OAuth stands for Open Authorization. It is commonly used to grant third-party applications limited access to user accounts and APIs. + - question: How does OAuth work? + answer: OAuth redirects the user to an authorization server, where they sign in and approve requested permissions. The client then receives an authorization code, exchanges it for a token, and uses that token to access an API. + - question: Is OAuth used for authentication or authorization? + answer: OAuth is primarily an authorization protocol. It controls what an application can access. OpenID Connect adds the authentication layer used for experiences such as “Sign in with Google.” + - question: What is an OAuth client? + answer: An OAuth client is the application requesting access to a user’s protected data. It redirects the user to the authorization server and uses the resulting token to call an API. +--- +Every time you click "Sign in with Google" or let a new app read your GitHub repositories, you are using OAuth. You are also, quietly, avoiding a much worse alternative: handing that app your actual password. + +OAuth exists to solve one specific problem. An application needs access to your data on another service, but you should never have to give it your credentials to get that access. This post explains what OAuth is, how OAuth 2.0 works, what its flows look like, and how to add it to your own app without building the hard parts yourself. + +# What is OAuth? + +OAuth is an open standard for **delegated authorization**. It lets one application access a user's data on another application, with the user's permission, without the user ever sharing their password. + +The name stands for "Open Authorization". The version in use almost everywhere today is OAuth 2.0, defined in [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749). When people say "OAuth" in 2026, they almost always mean OAuth 2.0. + +Here is the core idea. Instead of giving an app your password, you give it a **token**. The token grants limited, revocable access to a specific set of your data, and nothing more. You can hand a photo-printing service permission to read your Google Photos without also giving it the ability to read your email, change your password, or delete your account. + +## Why OAuth exists + +Before OAuth, the common pattern was the "password anti-pattern". If a third-party app wanted to access your data on another service, you gave it your username and password for that service, and it logged in as you. + +That approach fails on every dimension that matters: + +- **The app sees your real password.** It can store it, leak it, or use it for anything. +- **Access is all or nothing.** The app can do everything you can do, not just the one thing it needs. +- **You cannot revoke access selectively.** The only way to cut off one app is to change your password, which breaks every other app too. +- **There is no audit trail.** The service cannot tell your legitimate logins apart from the app acting on your behalf. + +OAuth was designed to fix all of this. Tokens are scoped, revocable, and traceable, and your password never leaves the service that owns it. + +# The four roles in OAuth + +OAuth defines four parties. Understanding them makes every flow easier to follow. + +- **Resource owner.** The user. You own the data and grant access to it. +- **Client.** The application requesting access to your data, for example a photo-printing app. +- **Authorization server.** The service that authenticates you and issues tokens, for example Google's login system. +- **Resource server.** The API that holds your data and accepts tokens, for example the Google Photos API. + +In many products the authorization server and resource server are run by the same company, so you may only notice two parties: the app you are using and the service you are logging in with. If you want a deeper breakdown of the client and server sides, see [OAuth server vs. OAuth client](/blog/post/oauth-server-vs-oauth-client-what-is-the-difference). + +# How does OAuth work? + +OAuth works by exchanging a user's consent for a short-lived token, then using that token to make API requests. The user approves access once, and the app receives a credential it can present instead of a password. + +Here is the standard sequence, using "Sign in with Google" as the example: + +1. **The app requests authorization.** You click "Sign in with Google". The app redirects you to Google's authorization server, along with details about what it wants access to. +2. **You authenticate and consent.** You log in to Google directly, on Google's own page, and approve the specific permissions the app is asking for. +3. **Google returns an authorization code.** Google redirects you back to the app with a temporary code. Notice the app still has not seen your password. +4. **The app exchanges the code for a token.** Behind the scenes, the app's server swaps the code with Google for an **access token**. +5. **The app uses the token.** The app calls the resource server's API with the token attached, and gets only the data the token permits. + +The key detail is step two. You authenticate on the provider's page, not the app's. The app never touches your credentials at any point in the flow. + +## Access tokens and refresh tokens + +OAuth 2.0 uses two kinds of tokens, and the difference matters. + +- **Access token.** A short-lived credential the app sends with each API request. It usually expires within minutes to hours, which limits the damage if it leaks. +- **Refresh token.** A longer-lived credential the app uses to get a new access token when the old one expires, without asking you to log in again. + +Short-lived access tokens plus refresh tokens are what let you stay signed in for weeks while keeping each individual credential low-risk. + +## Scopes + +A **scope** is a string that defines exactly what an access token is allowed to do. When an app requests authorization, it lists the scopes it needs, and the consent screen shows them to you in plain language. + +Scopes are how OAuth enforces least privilege. An app that only needs to read your profile should request a read-only profile scope, not full account access. As a user, the consent screen is your chance to check that an app is not asking for more than it should. + +# OAuth 2.0 flows explained + +OAuth 2.0 defines several **grant types**, often called flows. Each fits a different kind of client. Picking the right one is the main design decision when you implement OAuth. + +## Authorization code flow + +This is the default and most secure flow, used by web apps with a backend. The app receives a temporary authorization code in the browser, then exchanges it for tokens from its server, so the tokens never appear in the browser. This is the flow behind most "Sign in with..." buttons. + +## Authorization code flow with PKCE + +**PKCE** (Proof Key for Code Exchange, defined in [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636)) extends the authorization code flow for clients that cannot keep a secret, such as mobile apps and single-page apps. It adds a dynamically generated proof that ties the token exchange to the original request, blocking attackers who intercept the code. PKCE is now recommended for all clients, including those with a backend. + +## Client credentials flow + +This flow is for machine-to-machine access, where there is no user involved. A backend service authenticates as itself to access another service's API, using its own credentials rather than a user's consent. + +## Flows to avoid + +Two older flows are now discouraged: + +- **Implicit flow.** It returned tokens directly in the browser URL and is superseded by the authorization code flow with PKCE. +- **Resource owner password credentials flow.** It required the user to give their password to the app, which defeats the entire purpose of OAuth. Avoid it. + +The [OAuth 2.0 Security Best Current Practice](https://datatracker.ietf.org/doc/html/rfc9700) formalizes this guidance. For new apps, use the authorization code flow with PKCE unless you have a specific reason not to. + +# OAuth vs. authentication: what OAuth is not + +OAuth is an **authorization** protocol, not an authentication protocol. This distinction trips up a lot of developers, so it is worth being direct about. + +- **Authentication** answers "who are you?" +- **Authorization** answers "what are you allowed to do?" + +OAuth was built to answer the second question. It grants an app access to resources. It does not, on its own, verify identity in a standardized way. + +The protocol that adds a proper identity layer on top of OAuth 2.0 is **OpenID Connect (OIDC)**. When you "Sign in with Google" and the app learns who you are, OIDC is doing the identity part while OAuth handles the access. If your goal is user login, you want OAuth 2.0 with OpenID Connect, which is exactly what most providers give you out of the box. + +# How to add OAuth to your app + +You have two options: build an OAuth client yourself against each provider, or use an authentication service that wraps the flows for you. + +Building it yourself means registering an app with every provider, handling redirects, exchanging codes for tokens, storing and refreshing tokens securely, and keeping up with security best practices as they evolve. It is doable, but it is a lot of surface area to get right, and every mistake is a security bug. + +The faster path is to use a backend that implements the flows for you. [Appwrite Authentication](/docs/products/auth) supports [OAuth2 login](/docs/products/auth/oauth2) with more than 30 providers, including Google, GitHub, Apple, and Microsoft. You enable a provider in the console, add its credentials, and trigger the flow with a single SDK call. Appwrite handles the redirect, the token exchange, and session management. + +Here is what an OAuth2 login looks like with the Appwrite web SDK: + +```client-web +import { Client, Account, OAuthProvider } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +const account = new Account(client); + +account.createOAuth2Session({ + provider: OAuthProvider.Google, + success: 'https://example.com/success', + failure: 'https://example.com/failed' +}); +``` + +That single call kicks off the authorization code flow, redirects the user to Google, and returns them to your app with an active session. For a full walkthrough with a real frontend, see [how to set up Google auth with Appwrite and React](/blog/post/set-up-google-auth-appwrite-react). + +OAuth is also just one of several login methods. Appwrite pairs it with [email and password](/docs/products/auth/email-password), [passwordless authentication](/blog/post/improve-ux-passwordless-auth), phone OTP, and MFA, so you can offer OAuth alongside whatever else your users expect. + +# Getting started with OAuth in Appwrite + +OAuth solves a problem you should not solve with passwords: letting an app act on a user's behalf without holding their credentials. Once you understand the four roles, the token exchange, and the flows, the protocol stops feeling mysterious and starts feeling like the obvious way to handle third-party access. + +You do not need to implement OAuth from scratch to use it well. Appwrite gives you production-ready OAuth2 login across 30-plus providers, secure session handling, and the other auth methods your app will eventually need, all behind one set of APIs. Create a project, enable a provider, and you can have "Sign in with Google" working in an afternoon. + +## Resources + +- [Appwrite Authentication docs](/docs/products/auth) +- [OAuth2 login in Appwrite](/docs/products/auth/oauth2) +- [Set up Google auth with Appwrite and React](/blog/post/set-up-google-auth-appwrite-react) +- [OAuth server vs. OAuth client](/blog/post/oauth-server-vs-oauth-client-what-is-the-difference) +- [Sign up for Appwrite Cloud](https://cloud.appwrite.io/register) +- [Join the Appwrite Discord community](https://appwrite.io/discord) \ No newline at end of file diff --git a/static/images/blog/oauth-server-vs-oauth-client-what-is-the-difference/cover.avif b/static/images/blog/oauth-server-vs-oauth-client-what-is-the-difference/cover.avif new file mode 100644 index 0000000000..f0ed2e7f70 Binary files /dev/null and b/static/images/blog/oauth-server-vs-oauth-client-what-is-the-difference/cover.avif differ diff --git a/static/images/blog/what-is-oauth-a-beginners-guide/cover.avif b/static/images/blog/what-is-oauth-a-beginners-guide/cover.avif new file mode 100644 index 0000000000..2ba5492bc3 Binary files /dev/null and b/static/images/blog/what-is-oauth-a-beginners-guide/cover.avif differ