---
term: 'OAuth 2.0 y Login Social'
seoTitle: 'OAuth 2.0 y Login Social: flujos, tokens, PKCE, vinculación de cuentas'
headline: '¿Qué son OAuth 2.0 y el Login Social?'
slug: oauth-2-login-social
category: auth-security
shortDefinition: 'OAuth 2.0 es un estándar de autorización que permite a una app acceder a tu cuenta en otro servicio — el login social construye el inicio de sesión encima.'
relatedTerms:
  - json-web-token-jwt
  - passwordless-authentication
  - identity-access-management-iam
  - multi-factor-authentication-mfa
contrastsWith:
  - json-web-token-jwt
aboutTerms:
  - 'OAuth 2.0'
  - 'OpenID Connect (OIDC)'
  - 'Login Social'
  - 'PKCE'
faq:
  - question: '¿Qué es OAuth 2.0 en términos simples?'
    answer: 'Un estándar que permite a una app obtener acceso limitado a tu cuenta en otro servicio sin que le entregues tu contraseña. En lugar de credenciales, el servicio le emite a la app un token temporal y con scope — como una tarjeta de hotel que abre tu habitación y el gimnasio, pero no la oficina del gerente, y expira en el checkout.'
  - question: '¿OAuth es autorización o autenticación?'
    answer: 'Autorización — por el título de su propia especificación, el RFC 6749 es "The OAuth 2.0 Authorization Framework". Responde "¿a qué puede acceder esta app?", no "¿quién es este usuario?". El login sobre OAuth lo estandariza OpenID Connect, que agrega un ID token firmado que atestigua la identidad ante la app.'
  - question: '¿Cuál es la diferencia entre OAuth 2.0 y OpenID Connect?'
    answer: 'OpenID Connect es una capa delgada de identidad sobre OAuth 2.0: los mismos flujos, más un ID token firmado (un JWT dirigido a tu app, con claims de issuer, subject, audience y nonce) y un endpoint de userinfo. Todo botón real de "Iniciar sesión con…" es OIDC o un equivalente del proveedor — OAuth a secas no define cómo probar quién inició sesión.'
  - question: '¿Cuáles son los grant types de OAuth?'
    answer: 'Authorization code con PKCE para cualquier cosa que involucre a un usuario; client credentials para comunicación máquina a máquina; device authorization para TVs y CLIs; refresh token para renovar el acceso. Los grants implicit y password son legado — ambos fueron eliminados en OAuth 2.1, y ningún diseño nuevo debería usarlos.'
  - question: '¿Qué son los access tokens y los refresh tokens?'
    answer: 'El access token es la credencial de vida corta que la app presenta a la API — con scope, con expiración, muchas veces un JWT. El refresh token vive más y se intercambia por nuevos access tokens sin volver a molestar al usuario; la práctica moderna lo rota en cada uso, para que uno robado muera en el primer replay.'
  - question: '¿Qué es PKCE y por qué es obligatorio?'
    answer: 'Proof Key for Code Exchange (se pronuncia "pixie"): la app inicia el flujo con el hash de un secreto y debe presentar el original al canjear el authorization code, probando que quien canjea es quien inició. Diseñado para apps móviles, que no pueden guardar client secrets, defiende contra la interceptación de código — y OAuth 2.1 lo exige a todo cliente.'
  - question: '¿Qué es el login social y cómo funciona?'
    answer: 'Es OIDC empaquetado como botón: la app redirige al endpoint de autorización del proveedor; el usuario se autentica allá — la contraseña nunca toca la app — y consiente; el proveedor redirige de vuelta con un código de un solo uso; la app lo intercambia por tokens y lee el subject estable del ID token para crear o encontrar la cuenta local.'
  - question: '¿Es seguro el login social?'
    answer: 'En general, sí: el usuario hereda la autenticación endurecida y la MFA del proveedor en lugar de otra contraseña reutilizada. Los costos son el riesgo de concentración — una cuenta bloqueada o comprometida en el proveedor afecta a todas las apps río abajo — y el cuidado de implementación: la app debe anclar la identidad en el subject estable del proveedor y en claims verificados, nunca en un campo crudo de email.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'RFC 6749 — The OAuth 2.0 Authorization Framework'
    url: 'https://datatracker.ietf.org/doc/html/rfc6749'
  - name: 'RFC 7636 — Proof Key for Code Exchange (PKCE)'
    url: 'https://datatracker.ietf.org/doc/html/rfc7636'
  - name: 'OAuth 2.1 — consolidation draft'
    url: 'https://oauth.net/2.1/'
  - name: 'OpenID Connect Core 1.0'
    url: 'https://openid.net/specs/openid-connect-core-1_0.html'
  - name: 'OAuth — Wikipedia'
    url: 'https://en.wikipedia.org/wiki/OAuth'
cta:
  title: 'Login social sin la danza de redirects'
  text: 'Back4app envuelve el flujo completo: entrégale al SDK los tokens de un proveedor y logInWith los verifica del lado del servidor, crea o encuentra al usuario y emite tu sesión — con linkWith resolviendo la vinculación de cuentas en una sola llamada.'
  linkText: 'Empieza gratis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-08-31'
translationKey: oauth-2-social-login
---

**OAuth 2.0 es un estándar de autorización que permite a una app acceder a tu cuenta en otro servicio — el login social construye el inicio de sesión encima.** Los dos suelen explicarse por separado, y así es como la confusión sobrevive: el [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749) define la plomería (acceso delegado y con scope, sin compartir contraseñas), OpenID Connect agrega la capa de identidad, y el botón de "Iniciar sesión con…" es la funcionalidad de producto montada sobre ambos.

## Puntos clave

| Pregunta | Respuesta |
| --- | --- |
| OAuth 2.0 | Autorización delegada: tokens con scope y expiración en lugar de contraseñas |
| La confusión | OAuth responde *a qué puede acceder esta app* — OIDC responde *quién es este usuario* |
| El flujo moderno | Authorization code + PKCE — los grants implicit y password desaparecieron en 2.1 |
| Los tokens | Access (corto, con scope) · refresh (rotado) · ID (claims de identidad firmados) |
| Login social | OIDC en forma de botón: el proveedor autentica, tu app recibe claims verificados |

## El flujo authorization code, paso a paso

La danza de redirects detrás de cada pantalla de consentimiento — con los parámetros que importan:

```text
1  App → proveedor    /authorize?client_id=…&redirect_uri=…&scope=profile
                      &state=af3G…            ← guarda anti-CSRF, verificada a la vuelta
                      &code_challenge=hK9…    ← PKCE: hash de un secreto recién creado

2  Usuario ↔ proveedor   Inicia sesión ALLÁ (la contraseña nunca toca la app) y consiente

3  Proveedor → app    redirect_uri?code=SplxlO…&state=af3G…   ← código de un solo uso

4  App → proveedor    POST /token  { code, code_verifier }    ← prueba de PKCE
   Proveedor → app    { access_token, refresh_token, id_token }

5  App → API          Authorization: Bearer <access_token>
```

Así se ve cuando un backend lo envuelve — tokens del proveedor entran, sesión verificada sale:

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// Social login: the provider's tokens become a user session
const user = await Parse.User.logInWith('apple', {
  authData: { id: appleUserId, token: identityToken },
});
// First login creates the user; later logins match — session token issued

// Account linking: attach a second provider to the same user
await user.linkWith('facebook', { authData: fbAuthData });
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// Social login: the provider's tokens become a user session
final user = ParseUser.forQuery();
final response = await user.loginWith(
  'apple',
  apple(identityToken, appleUserId),
);
// First login creates the user; later logins match — session token issued

// Account linking: attach a second provider to the same user
await user.linkWith('facebook', facebook(token, fbUserId, expiresAt));
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// Social login: the provider's tokens become a user session
let user = try await User.apple.login(
    user: appleUserId,
    identityToken: identityTokenData
)
// First login creates the user; later logins match — session token issued

// Account linking: attach a second provider to the same user
try await user.facebook.link(userId: fbUserId, accessToken: fbAccessToken)
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// Social login: the provider's tokens become a user session
val authData = mapOf("id" to appleUserId, "token" to identityToken)
ParseUser.logInWithInBackground("apple", authData).continueWith { task ->
    val user = task.result
    // First login creates the user; later logins match — session token issued

    // Account linking: attach a second provider to the same user
    user.linkWithInBackground("facebook", fbAuthData)
}
```

## Los cuatro roles

| Rol | Quién es | En términos de "Iniciar sesión con…" |
| --- | --- | --- |
| Resource owner | El usuario | Tú |
| Client | La app que pide acceso | La app que muestra el botón |
| Authorization server | Emite códigos y tokens | Las páginas de login del proveedor de identidad |
| Resource server | La API que custodia los datos | La API de perfil/usuario del proveedor |

```mermaid
flowchart LR
  accTitle: Flujo authorization code de OAuth 2.0 con PKCE
  accDescr: La app cliente redirige al usuario al authorization server con un desafío PKCE; el usuario se autentica y consiente allí; el servidor redirige de vuelta con un código de un solo uso; el cliente intercambia el código más el verificador PKCE por access, refresh e ID tokens, y luego llama al resource server con el access token.
  U["Usuario<br/>(resource owner)"] -->|"1 · redirigido con<br/>state + code_challenge"| AS["Authorization server<br/>login + consentimiento"]
  AS -->|"2 · código de un solo uso"| C["App cliente"]
  C -->|"3 · code + code_verifier"| AS
  AS -->|"4 · access · refresh · ID tokens"| C
  C -->|"5 · Bearer access_token"| RS["Resource server<br/>(API)"]
```

## Grant types: qué flujo usar y qué cambió OAuth 2.1

| Grant | Para | ¿Usuario presente? | Estado en [OAuth 2.1](https://oauth.net/2.1/) |
| --- | --- | --- | --- |
| Authorization code + PKCE | Web, mobile, SPA — cualquier cosa con un usuario | Sí | **El default — PKCE ahora obligatorio para todos los clientes** |
| Client credentials | Máquina a máquina, cuentas de servicio | No | Se mantiene |
| Device authorization | TVs, consolas, CLIs | Sí, en un segundo dispositivo | Se mantiene |
| Refresh token | Renovar el acceso en silencio | No | Se mantiene — rotación o sender-constraining exigidos para clientes públicos |
| Implicit | SPAs legadas (tokens en fragmentos de URL) | Sí | **Eliminado** |
| Password (ROPC) | La app recoge la contraseña por sí misma | Sí | **Eliminado** — derrota el propósito entero |

OAuth 2.1 es consolidación, no revolución: las eliminaciones de arriba, más redirect URIs de coincidencia exacta y la prohibición de bearer tokens en query strings — las lecciones de seguridad acumuladas de una década plegadas de vuelta en un solo documento. Los explicadores definicionales en gran parte no se han puesto al día; varios todavía enseñan el flujo implicit sin ninguna advertencia.

## OAuth vs. OpenID Connect: autorización vs. autenticación

La frase que todo el mundo repite — "OAuth no es autenticación" — merece su mecanismo, porque el mecanismo es lo que vuelve explotable el login ingenuo:

| | Access token (OAuth) | ID token (OIDC) |
| --- | --- | --- |
| Dirigido a | El resource server (API) | **Tu app** (`aud` = tu client ID) |
| Prueba | Este portador puede acceder a estos scopes | Este usuario (`sub`) se autenticó en este emisor (`iss`), ahora (`iat`/`exp`), para este login (`nonce`) |
| Formato | Muchas veces opaco para el cliente | [JWT](/glossary/es/json-web-token-jwt/) firmado que tu app debe validar |
| ¿Sirve para iniciar sesión? | **No** — cualquier app autorizada por el usuario tiene uno; no dice nada sobre quién está presente | Sí — ese es exactamente su trabajo |

"Iniciar sesión con un access token a secas" falla porque los access tokens son evidencia transferible de *permiso*, no de *presencia*: una app maliciosa que obtuvo un token para sus propios fines podría reproducirlo en otro lugar para hacerse pasar por el usuario. [OpenID Connect](https://openid.net/specs/openid-connect-core-1_0.html) existe precisamente para cerrar esa brecha — los mismos flujos, más una aserción de identidad vinculada criptográficamente a tu app.

## Login social: el botón encima de la plomería

El login social es OIDC empaquetado como UX: el proveedor autentica, tu app recibe claims verificados y crea o encuentra una cuenta — ninguna contraseña almacenada, ningún flujo de restablecimiento que mantener, la MFA del proveedor heredada gratis. Los trade-offs de producto merecen números honestos. Las afirmaciones de 20–50% de aumento en registros son folclore de proveedor; las pruebas controladas han medido algo más cercano al 3% — aunque cerca de un tercio de los inicios de sesión de consumo hoy llega por la vía social, señal clara de que los usuarios quieren la opción. Las prácticas que de verdad mueven la conversión: ofrece **dos o tres proveedores** que tu audiencia usa (la "parrilla de salida" de botones perjudica de forma medible), mantén siempre la alternativa por email, y ten presente que los redirects de OAuth se rompen dentro de WebViews embebidas en apps — una causa real de fallas de registro en mobile. Dos datos específicos de proveedor pesan lo suficiente para nombrarlos: **Sign in with Apple** emite direcciones de relay privado (`…@privaterelay.appleid.com`), así que la vinculación por email y las listas de correo deben esperar aliases opacos — y las reglas de la App Store exigen que las apps que ofrecen login de terceros ofrezcan también el de Apple.

## Vinculación de cuentas y la trampa del email

La misma persona va a llegar desde dos proveedores, y ambos van a reportar `ada@example.com`. La regla que evita la vulnerabilidad clásica: **la identidad se ancla en el identificador `sub` estable del proveedor, nunca en el email solo.** Los emails cambian, se reciclan y — el filo cortante — no siempre están verificados: una clase de vulnerabilidades de 2023 mostró que las apps que confiaban en un claim de email no verificado en los tokens de un gran proveedor quedaban abiertas a robo de cuenta por cualquiera capaz de fijar ese email en su propia cuenta del proveedor. Vincula automáticamente solo emails que el proveedor atestigua como verificados; de lo contrario, pídele al usuario que vincule de forma explícita. Y planifica la salida: los usuarios bloqueados en un proveedor (pasa sin aviso) pierden todas las apps río abajo, a menos que hayas ofrecido un segundo método vinculado — por eso "un método de login por usuario" es un generador de tickets de soporte disfrazado de simplicidad.

## Casos de uso comunes

- **Inicio de sesión en apps de consumo** — el login social canónico: menos fricción, MFA heredada, ninguna base de contraseñas que vulnerar.
- **Acceso a APIs de terceros** — el caso original de OAuth: una app de agenda leyendo tu calendario sin tu contraseña.
- **Autenticación máquina a máquina** — client credentials entre servicios, sin usuario a la vista.
- **Identidad multiproveedor** — una cuenta, varios métodos de login vinculados, desvinculación y recuperación por usuario.
- **Puente hacia SSO empresarial** — el mismo patrón OIDC apuntado a un proveedor de identidad corporativo en lugar de uno social.

## ¿Deberías ofrecer login social? Matriz de decisión

| Tu situación | Inclinación |
| --- | --- |
| App de consumo, audiencia mayormente mobile | Sí — 2–3 proveedores + alternativa por email |
| App iOS que ofrece cualquier login de terceros | El login de Apple se vuelve obligatorio — planifica para emails de relay |
| Producto B2B/empresarial | OIDC sí, pero hacia el [SSO](/glossary/es/single-sign-on-sso/) corporativo, no el social |
| Datos regulados, ciclo de vida de cuenta estricto | Cuidado — el bloqueo en el proveedor y la prueba de identidad necesitan respuestas |
| MVP que necesita auth esta semana | Sí, vía un backend que envuelva los flujos |
| Usuarios sin cuenta en los grandes proveedores | Email/passwordless primero; social como opción |

## Limitaciones y trade-offs

- **Heredas las decisiones del proveedor.** Pantallas de consentimiento, duración de sesiones, recuperación de cuentas y deprecaciones ocurren en su calendario, no en el tuyo.
- **El riesgo de concentración es real.** Una caída del proveedor o un bloqueo de cuenta es una caída de tu login; los métodos vinculados de respaldo son la mitigación, no un extra opcional.
- **La flexibilidad de OAuth es su debilidad histórica.** Un framework con opciones invita combinaciones inseguras — el 2.1 existe porque flujos implicit, redirects con comodín y refresh tokens sin rotación seguían llegando a producción.
- **Los flujos de redirect tienen filos cortantes.** `state` (CSRF), redirect URIs exactas (open redirect y robo de código) y PKCE (interceptación) están cada uno a un parámetro olvidado de un incidente.
- **Los claims sociales son un piso, no un perfil.** Recibes subject, email, nombre — los atributos más allá de eso siguen necesitando tu propio onboarding, y los relays de privacidad significan que hasta el email puede ser un alias.

## OAuth y el login social en Back4app

Back4app es una plataforma open-source de Backend as a Service (BaaS) que combina base de datos gestionada, APIs REST y GraphQL generadas automáticamente, autenticación, almacenamiento de archivos y funciones serverless con Cloud Code. Los flujos de arriba colapsan en las pestañas de código: el cliente obtiene los tokens del proveedor de forma nativa, se los entrega a `logInWith`, y los adaptadores de autenticación de Back4app los verifican del lado del servidor contra el proveedor antes de crear o encontrar el `User` — las identidades de proveedor viven en bloques `authData` por proveedor, anclados en el subject estable, que es la regla de vinculación de cuentas impuesta por construcción. `linkWith` acopla proveedores adicionales (o una credencial de email) al mismo usuario, respondiendo al problema del bloqueo en una sola llamada, y el token de sesión que tu app recibe funciona en las APIs REST, GraphQL y Live Query, con [ACLs](/glossary/access-control-lists-acl/) y permisos a nivel de clase decidiendo qué puede tocar. La danza de redirects, la verificación de tokens y los casos límite de vinculación llegan como comportamiento de plataforma — configuras los proveedores en el panel y entregas el botón.
