PHPackages                             laramicrosoft/auth - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. laramicrosoft/auth

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

laramicrosoft/auth
==================

LaraMicrosoft-Auth: autenticación social con Microsoft Entra ID (Office 365). Integrable con frontends Vue, Nuxt o React.

v1.2(2mo ago)04↓100%MITPHPPHP &gt;=8.4

Since Mar 8Pushed 2mo agoCompare

[ Source](https://github.com/wramirez83/LaraMicrosoft-Auth)[ Packagist](https://packagist.org/packages/laramicrosoft/auth)[ RSS](/packages/laramicrosoft-auth/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (2)Versions (4)Used By (0)

LaraMicrosoft-Auth
==================

[](#laramicrosoft-auth)

Librería PHP para autenticación social con **Microsoft Entra ID** (Office 365) mediante OAuth 2.0. Pensada para backends en PHP (Laravel, Slim, etc.) que exponen la lógica de login; el frontend (Vue, Nuxt, React) solo redirige al usuario a Microsoft y envía el código de autorización de vuelta al backend.

- **PHP 8.4+**
- **Flujo:** Authorization Code (backend confidencial)
- **Frontend:** Cualquier SPA o SSR (Vue, Nuxt, React, etc.)

---

Índice
------

[](#índice)

- [Requisitos](#requisitos)
- [Instalación](#instalaci%C3%B3n)
- [Flujo de autenticación](#flujo-de-autenticaci%C3%B3n)
- [Registro en Azure (Entra ID)](#registro-en-azure-entra-id)
- [Configuración en el backend](#configuraci%C3%B3n-en-el-backend)
- [Endpoints del backend](#endpoints-del-backend)
- [Integración en el frontend](#integraci%C3%B3n-en-el-frontend)
- [Referencia de la API](#referencia-de-la-api)
- [Datos que devuelve Office 365](#datos-que-devuelve-office-365)
- [Opciones de configuración](#opciones-de-configuraci%C3%B3n)
- [Solución de problemas](#soluci%C3%B3n-de-problemas)
- [Seguridad](#seguridad)
- [Licencia](#licencia)

---

Requisitos
----------

[](#requisitos)

- **PHP** &gt;= 8.4
- **Composer** 2.x
- **Aplicación registrada** en [Azure Portal](https://portal.azure.com) (Microsoft Entra ID) con Client ID, Client Secret y URI de redirección configurados

---

Instalación
-----------

[](#instalación)

```
composer require laramicrosoft/auth
```

---

Flujo de autenticación
----------------------

[](#flujo-de-autenticación)

```
┌─────────────┐     GET /auth/entra/url      ┌─────────────┐
│  Frontend   │ ──────────────────────────► │   Backend    │
│ (Vue/React) │ ◄──────────────────────────  │    (PHP)     │
└──────┬──────┘     { url, state }          └──────┬──────┘
       │                                            │
       │  redirect usuario a url                     │ guarda state en sesión
       ▼                                            │
┌─────────────┐                                     │
│  Microsoft  │  usuario inicia sesión             │
│  Entra ID   │  y acepta permisos                  │
└──────┬──────┘                                     │
       │ redirect a redirect_uri?code=...&state=... │
       ▼                                            │
┌─────────────┐     POST /auth/entra/callback       │
│  Frontend   │  { code, state } ─────────────────►│
│  (callback) │ ◄───────────────────────────────────│  valida state, canjea
└─────────────┘     sesión / token / cookie         │  code por token y usuario

```

1. El frontend pide al backend la **URL de autorización** (y opcionalmente un `state`).
2. El backend genera la URL de Microsoft, guarda el `state` en sesión y devuelve `{ url, state }`.
3. El frontend redirige al usuario a esa URL; el usuario inicia sesión en Microsoft.
4. Microsoft redirige a tu `redirect_uri` con `code` y `state` en la query.
5. El frontend envía `code` y `state` al backend; el backend valida el `state`, canjea el `code` por tokens y usuario, y establece la sesión (o devuelve un token).

---

Registro en Azure (Entra ID)
----------------------------

[](#registro-en-azure-entra-id)

### Pasos

[](#pasos)

1. Entra en [Azure Portal](https://portal.azure.com) → **Microsoft Entra ID** → **Registros de aplicaciones** → **Nuevo registro**.
2. **Nombre**: por ejemplo `Mi App` o `LaraMicrosoft-Auth Demo`.
3. **Tipos de cuenta admitidos**:

    - **Solo mi organización**: solo usuarios de tu tenant.
    - **Cualquier organización**: cuentas laborales o escolares de cualquier tenant.
    - **Cuentas personales y laborales**: incluye cuentas Microsoft personales (outlook.com, etc.).
4. **URI de redirección**:

    - Tipo **Web**.
    - URL donde Microsoft enviará al usuario tras el login. Debe coincidir exactamente con la ruta de callback de tu app (backend o frontend), por ejemplo:
        - Producción: `https://tu-dominio.com/auth/entra/callback`
        - Local: `http://localhost:3000/auth/callback` (ajusta puerto y ruta a tu app).
5. Tras crear el registro, anota:

    - **Id. de aplicación (cliente)** → lo usarás como `client_id`.
    - **Id. de directorio (inquilino)** → lo usarás como `tenant` (o `common` para multi-tenant).
6. **Certificados y secretos** → **Nuevo secreto de cliente** → copia el **Valor** (solo se muestra una vez) → `client_secret`.
7. **Permisos de API** → **Agregar un permiso** → **Microsoft Graph** → **Permisos delegados**. Añade al menos:

    - `openid`
    - `profile`
    - `email`
    - `User.Read`

### Resumen de valores

[](#resumen-de-valores)

ParámetroDónde se obtiene`client_id`Registro de la aplicación → Información esencial`client_secret`Certificados y secretos → Valor del secreto`tenant`Información esencial → Id. de directorio, o `common``redirect_uri`La URL que configuraste en URI de redirección---

Configuración en el backend
---------------------------

[](#configuración-en-el-backend)

Crea la configuración a partir de un array (por ejemplo variables de entorno):

```
use LaraMicrosoft\Auth\Config\EntraIdConfig;
use LaraMicrosoft\Auth\EntraIdAuthService;

$config = EntraIdConfig::fromArray([
    'client_id'     => getenv('ENTRA_CLIENT_ID'),
    'client_secret' => getenv('ENTRA_CLIENT_SECRET'),
    'redirect_uri'  => getenv('ENTRA_REDIRECT_URI'),  // ej. https://tu-dominio.com/auth/entra/callback
    'tenant'        => getenv('ENTRA_TENANT_ID') ?: 'common',
    'scopes'        => ['openid', 'profile', 'email', 'User.Read'],
]);

$entraAuth = new EntraIdAuthService($config);
```

Ejemplo de `.env`:

```
ENTRA_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ENTRA_CLIENT_SECRET=tu~secreto~de~cliente
ENTRA_REDIRECT_URI=https://tu-dominio.com/auth/entra/callback
ENTRA_TENANT_ID=common
```

La librería exige que `client_id`, `client_secret` y `redirect_uri` no estén vacíos; si lo están, se lanzará una excepción al crear la config.

---

Endpoints del backend
---------------------

[](#endpoints-del-backend)

Tu aplicación debe exponer al menos dos rutas que usen `EntraIdAuthService`.

### 1. Obtener URL de login

[](#1-obtener-url-de-login)

El frontend llama a esta ruta para obtener la URL a la que redirigir al usuario.

**Ejemplo (pseudo-framework):**

```
// GET /api/auth/entra/url

$state = bin2hex(random_bytes(16));
$_SESSION['entra_oauth_state'] = $state;  // o Redis, etc.

$result = $entraAuth->getAuthorizationUrl($state);

return [
    'url'   => $result['url'],
    'state' => $result['state'],
];
```

El frontend guarda `state` (por ejemplo en `sessionStorage`) y redirige al usuario a `url`.

### 2. Callback: canjear código por token y usuario

[](#2-callback-canjear-código-por-token-y-usuario)

Microsoft redirige al usuario a tu `redirect_uri` con `?code=...&state=...`. El frontend (o el backend si el callback es una ruta del propio backend) debe enviar `code` y `state` a esta ruta.

**Ejemplo (pseudo-framework):**

```
// POST /api/auth/entra/callback
// Body: { "code": "...", "state": "..." }

$code  = $request->input('code');
$state = $request->input('state');
$expectedState = $_SESSION['entra_oauth_state'] ?? null;

try {
    $result = $entraAuth->exchangeCodeAndGetUser($code, $state, $expectedState);
} catch (\LaraMicrosoft\Auth\Exception\InvalidStateException $e) {
    // State no coincide: posible CSRF
    return response()->json(['error' => 'invalid_state'], 400);
} catch (\LaraMicrosoft\Auth\Exception\TokenExchangeException $e) {
    // Error al canjear el código (código expirado, revocado, etc.)
    return response()->json(['error' => 'token_exchange_failed'], 400);
}

$accessToken = $result['token'];
$user        = $result['user'];

// Ejemplo de datos del usuario
$user->getId();       // sub/oid de Microsoft
$user->getEmail();    // email o preferred_username
$user->getName();     // nombre completo
$user->getGivenName();
$user->getFamilyName();
$user->toArray();     // todos los claims

// Aquí: crear o actualizar usuario en tu BD, iniciar sesión, devolver cookie o JWT al frontend
```

---

Integración en el frontend
--------------------------

[](#integración-en-el-frontend)

### Vue 3 o React (fetch)

[](#vue-3-o-react-fetch)

**Iniciar login:**

```
async function loginWithEntra() {
  const res = await fetch('/api/auth/entra/url', { credentials: 'include' });
  const { url, state } = await res.json();
  sessionStorage.setItem('entra_oauth_state', state);
  window.location.href = url;
}
```

**Página de callback** (ruta que hayas configurado como `redirect_uri` en Azure):

```
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const state = params.get('state');

if (code && state) {
  const res = await fetch('/api/auth/entra/callback', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify({ code, state }),
  });
  if (res.ok) {
    // Backend habrá establecido cookie/sesión; redirigir al dashboard
    window.location.href = '/dashboard';
  }
}
```

### Nuxt 3

[](#nuxt-3)

**Página de login** (`pages/login.vue`):

```

async function loginWithEntra() {
  const { data } = await useFetch('/api/auth/entra/url');
  if (data.value?.url) {
    sessionStorage.setItem('entra_oauth_state', data.value.state);
    await navigateTo(data.value.url, { external: true });
  }
}

  Iniciar sesión con Office 365

```

**Página de callback** (`pages/auth/callback.vue`): la URL de esta página debe ser exactamente la configurada como `redirect_uri` en Azure.

```

const route = useRoute();
const code = route.query.code;
const state = route.query.state;

if (code && state) {
  await $fetch('/api/auth/entra/callback', {
    method: 'POST',
    body: { code, state },
  });
  await navigateTo('/');
}

```

---

Referencia de la API
--------------------

[](#referencia-de-la-api)

MétodoDescripción`getAuthorizationUrl(?string $state = null)`Devuelve `['url' => string, 'state' => string]`. Si no pasas `state`, se genera uno aleatorio.`exchangeCodeForToken(string $code, string $state, ?string $expectedState)`Canjea el código por un `AccessToken`. Lanza `InvalidStateException` o `TokenExchangeException` si falla.`getUser(AccessToken $token)`Obtiene el usuario desde Microsoft (userinfo) como `EntraIdResourceOwner`.`exchangeCodeAndGetUser(string $code, string $state, ?string $expectedState)`Equivalente a `exchangeCodeForToken` + `getUser`; devuelve `['token' => AccessToken, 'user' => EntraIdResourceOwner]`.`exchangeCodeAndGetFullResponse(string $code, string $state, ?string $expectedState)`Igual que arriba pero devuelve **todos los datos crudos** de O365: `['token_response' => array, 'user' => array]`. Ver [Datos que devuelve Office 365](#datos-que-devuelve-office-365).`getConfig()`Devuelve la instancia de `EntraIdConfig` usada.### EntraIdResourceOwner (usuario)

[](#entraidresourceowner-usuario)

- `getId()` – identificador (sub/oid)
- `getEmail()` – email o preferred\_username
- `getName()` – nombre completo
- `getGivenName()` – nombre
- `getFamilyName()` – apellido
- `toArray()` – **array con todos los claims** que devuelve Microsoft (userinfo)

---

Datos que devuelve Office 365
-----------------------------

[](#datos-que-devuelve-office-365)

Para ver **toda la respuesta** de Entra ID (tokens + usuario), usa `exchangeCodeAndGetFullResponse()`:

```
$full = $entraAuth->exchangeCodeAndGetFullResponse($code, $state, $expectedState);

// Respuesta del endpoint de tokens (POST .../oauth2/v2.0/token)
$full['token_response'];
// Ejemplo: access_token, refresh_token, expires, token_type, scope, id_token (si aplica), etc.

// Todos los claims del usuario (userinfo / OpenID Connect)
$full['user'];
// Ejemplo: sub, oid, name, given_name, family_name, email, preferred_username, etc.
```

### Campos típicos en `token_response`

[](#campos-típicos-en-token_response)

CampoDescripción`access_token`Token para llamar a APIs (p. ej. Microsoft Graph).`refresh_token`Presente si pediste el scope `offline_access`; sirve para renovar el access\_token.`expires`Timestamp Unix de expiración del access\_token.`token_type`Normalmente `Bearer`.`scope`Scopes concedidos (separados por espacio).`id_token`JWT con claims del usuario (si pediste `openid`).### Campos típicos en `user` (userinfo)

[](#campos-típicos-en-user-userinfo)

CampoDescripción`sub`Identificador único del usuario (claim estándar OIDC).`oid`Object ID en Microsoft Entra ID.`name`Nombre completo.`given_name`Nombre.`family_name`Apellido.`email`Email (puede no venir si no está configurado).`preferred_username`UPN o email que usa para iniciar sesión.`tenant_id` / `tid`ID del tenant.Microsoft puede devolver más campos según permisos y configuración del tenant. Con `exchangeCodeAndGetFullResponse()` o `$user->toArray()` tienes siempre el array completo para inspeccionar o guardar.

---

Opciones de configuración
-------------------------

[](#opciones-de-configuración)

ClaveTipoRequeridoDescripción`client_id`stringSíApplication (client) ID de Azure.`client_secret`stringSíValor del secreto de cliente.`redirect_uri`stringSíURI de redirección registrada en Azure.`tenant`stringNo`common`, `organizations`, `consumers` o ID del tenant. Por defecto: `common`.`scopes`string\[\]NoScopes OAuth; por defecto: `['openid', 'profile', 'email', 'User.Read']`.`prompt`stringNoComportamiento de login: `login`, `none`, `consent`, `select_account`.---

Solución de problemas
---------------------

[](#solución-de-problemas)

### AADSTS900144 — "The request body must contain the following parameter: 'client\_id'"

[](#aadsts900144--the-request-body-must-contain-the-following-parameter-client_id)

Significa que la petición al endpoint de tokens de Microsoft no incluye `client_id`.

- Comprueba que en tu `.env` (o config) tengas **ENTRA\_CLIENT\_ID** con el valor del **Id. de aplicación (cliente)** del registro en Azure.
- Asegúrate de que la app lee esa variable al construir `EntraIdConfig` y que no esté vacía. Si está vacía, la librería lanzará una excepción al crear la config.

### AADSTS50011 — "Reply URL does not match"

[](#aadsts50011--reply-url-does-not-match)

La `redirect_uri` que envías no coincide con ninguna de las URLs configuradas en el registro de la aplicación.

- En Azure → Registro de la aplicación → Autenticación → URI de redirección, añade exactamente la misma URL que usas en `redirect_uri` (incluyendo protocolo, dominio, puerto y path).

### Invalid state / Estado inválido

[](#invalid-state--estado-inválido)

- El `state` que envías en el callback debe ser el mismo que guardaste al generar la URL (por ejemplo en sesión).
- Asegúrate de que el frontend envía el mismo `state` que recibió al pedir la URL y de que el backend compara con el guardado (por sesión o almacén equivalente).

### Código ya canjeado o expirado

[](#código-ya-canjeado-o-expirado)

Los códigos de autorización son de un solo uso y caducan en poco tiempo (aprox. 1 minuto). Si el usuario recarga la página de callback o se envía el mismo código dos veces, Microsoft devolverá error; en ese caso hay que pedir de nuevo la URL de login e iniciar el flujo otra vez.

---

Seguridad
---------

[](#seguridad)

- **State:** Siempre genera y valida un `state` aleatorio para evitar ataques CSRF. Guarda el `state` en sesión (o almacén vinculado al usuario) al generar la URL y compáralo en el callback.
- **Client secret:** No expongas nunca el `client_secret` en el frontend; úsalo solo en el backend.
- **HTTPS:** En producción usa siempre HTTPS para `redirect_uri` y para las rutas de tu API.
- **Redirect URI:** Registra solo las URLs que realmente uses; evita wildcards si no son necesarios.

---

Licencia
--------

[](#licencia)

MIT.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance87

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

62d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/dd11480feff23989c23a202a8601179e35a4dc5430c17fbcc67db23f3bbcac8e?d=identicon)[wramirez83](/maintainers/wramirez83)

---

Top Contributors

[![wramirez83](https://avatars.githubusercontent.com/u/14268794?v=4)](https://github.com/wramirez83 "wramirez83 (4 commits)")

---

Tags

laraveloauth2microsoftOpenID Connectazure-adOffice365social-authentra-idlaramicrosoft

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/laramicrosoft-auth/health.svg)

```
[![Health](https://phpackages.com/badges/laramicrosoft-auth/health.svg)](https://phpackages.com/packages/laramicrosoft-auth)
```

###  Alternatives

[thenetworg/oauth2-azure

Azure Active Directory OAuth 2.0 Client Provider for The PHP League OAuth2-Client

2509.6M48](/packages/thenetworg-oauth2-azure)[ronvanderheijden/openid-connect

OpenID Connect support to the PHP League's OAuth2 Server. Compatible with Laravel Passport.

61755.5k](/packages/ronvanderheijden-openid-connect)[stevenmaguire/oauth2-microsoft

Microsoft OAuth 2.0 Client Provider for The PHP League OAuth2-Client

742.3M12](/packages/stevenmaguire-oauth2-microsoft)[jeremy379/laravel-openid-connect

OpenID Connect support to the PHP League's OAuth2 Server. Compatible with Laravel Passport.

55342.3k2](/packages/jeremy379-laravel-openid-connect)[ekapusta/oauth2-esia

Allows to authenticate in ESIA and get authenticated individual personal information.

73189.8k1](/packages/ekapusta-oauth2-esia)[kronthto/laravel-oauth2-login

Provides a middleware to protect resources requiring an OAuth2 login

2117.5k1](/packages/kronthto-laravel-oauth2-login)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
