# Sign-in Providers

> Let people sign in to your app with Google, Azure AD (Microsoft Entra ID), AWS Cognito, your own users table or a system of your own - API Maker checks their token, finds the person in a table of yours and runs the call with their groups.

Source: https://docs.apimaker.dev/v4/docs/authorization/sign-in-providers.html

Your app signs people in, and sends the token it gets to API Maker with every call. An **auth provider** checks that token, finds the person in a table of yours, and runs the call with the [groups](https://docs.apimaker.dev/v4/docs/apis-security/api-group-permission.html) of that person. Make one on `Security → Auth Providers`.

| Provider | The app sends | Your code reads |
|---|---|---|
| [Your users table](https://docs.apimaker.dev/v4/docs/authorization/AMDB.html) | `x-am-user-authorization` : a token of API Maker, from a username and a password | `g.req.auth.authAMDB` |
| [Google](https://docs.apimaker.dev/v4/docs/authorization/sign-in-providers.html#google) | `x-google-authorization` : the id token of Google | `g.req.auth.authGoogle` |
| [Azure AD](https://docs.apimaker.dev/v4/docs/authorization/sign-in-providers.html#azure) (Microsoft Entra ID) | `x-azure-authorization` : the token of Microsoft | `g.req.auth.authAzure` |
| [AWS Cognito](https://docs.apimaker.dev/v4/docs/authorization/sign-in-providers.html#aws) | `x-aws-authorization` : the token of the user pool | `g.req.auth.authAWS` |
| [A provider of your own](https://docs.apimaker.dev/v4/docs/authorization/sign-in-providers.html#custom) | `x-custom-authorization` : whatever your system issues | `g.req.auth.authCustom` |

The call carries the token of the [API user](https://docs.apimaker.dev/v4/docs/apis-security/api-user-permission.html) in `x-am-authorization` as well : the application and the person both need a group which grants the API.

## Google

**The provider**

```typescript
import * as T from 'types';

let googleTokenGenerator: T.IAuthTokenGoogle & { name: string; testObj?: any; } = {
    name: 'google_token_generator',
    clientId: '<OAuth client id>.apps.googleusercontent.com', // the aud of your tokens : a list when several apps sign in
    sourceFieldOfUniqueId: 'sub',        // or 'email'
    groupsDataSource: { instance: 'mongodb', database: 'shop', collection: 'users', targetFieldForUniqueId: 'google_sub', groupsColumn: 'groups', select: { name: 1, email: 1 } },
};
module.exports = googleTokenGenerator;
```

Google signs the id tokens of every application with the same keys. `clientId` is the application a token has to be made for (its `aud` claim) : the OAuth client id of your app, or a list of them. Without `clientId`, a token Google made for any other site is taken too : that site could call your APIs as each person who signed in there. The [API Security Report](https://docs.apimaker.dev/v4/docs/apis-security/api-security-report.html) lists such a provider as **takes the Google tokens of any application** (high).

## Azure AD

**The provider**

```typescript
import * as T from 'types';

let azureTokenGenerator: T.IAuthTokenAzureAD & { name: string; testObj?: any; } = {
    name: 'azure_token_generator',
    appId: '<application (client) id>',
    tenant: '<directory (tenant) id>',
    audience: '<application (client) id>',                                   // the aud of your tokens
    issuer: 'https://login.microsoftonline.com/<directory (tenant) id>/v2.0', // the iss of your tokens
    maxRetries: 3,                       // fetching the signing keys
    sourceFieldOfUniqueId: 'oid',        // or 'preferred_username' for the email
    groupsDataSource: { instance: 'mongodb', database: 'shop', collection: 'users', targetFieldForUniqueId: 'azure_oid', groupsColumn: 'groups', select: { name: 1, email: 1 } },
};
module.exports = azureTokenGenerator;
```

Microsoft signs the tokens of every application with the same keys. The keys prove that Microsoft made a token, not that it was made for your application :

- `audience` is the application a token has to be made for (its `aud` claim) : the application (client) id, or the Application ID URI (`api://...`) when your tokens carry that.
- `issuer` is the directory a token has to come from (its `iss` claim) : `https://login.microsoftonline.com/<directory id>/v2.0` for tokens of version 2, `https://sts.windows.net/<directory id>/` for tokens of version 1.
- Either can be a list : a token which carries one of its entries is taken.
- Left empty (or an empty list), the claim is not checked. A token Microsoft made for another application is then taken too, and the [API Security Report](https://docs.apimaker.dev/v4/docs/apis-security/api-security-report.html) lists the provider as **takes the Azure tokens of any application** (high).

Paste one of your tokens in [jwt.ms](https://jwt.ms) to read its `aud` and `iss`.

## AWS Cognito

**The provider**

```typescript
import * as T from 'types';

let awsTokenGenerator: T.IAuthTokenAWS & { name: string; testObj?: any; } = {
    name: 'aws_token_generator',
    cognitoUserPoolId: 'us-east-1_xxxxxx',
    region: 'us-east-1',
    tokenUse: 'access',                 // 'access' | 'id' : which Cognito token the app sends
    tokenExpiration: 3600000,           // milliseconds, at most 3600000
    sourceFieldOfUniqueId: 'sub',       // the claim which identifies the person
    groupsDataSource: { instance: 'mongodb', database: 'shop', collection: 'users', targetFieldForUniqueId: 'cognito_sub', groupsColumn: 'groups', select: { name: 1, email: 1 } },
};
module.exports = awsTokenGenerator;
```

- `tokenUse` is the Cognito token the app sends, `access` or `id`. The user pool and the region come from AWS.

## The groups of the person

- `sourceFieldOfUniqueId` is the claim of the token which identifies the person (an email, `sub`, `oid`).
- `groupsDataSource` names the table of yours which holds that person : `targetFieldForUniqueId` is the column with the same value, `groupsColumn` the comma separated [groups](https://docs.apimaker.dev/v4/docs/apis-security/api-group-permission.html) of the person, `select` the columns to put in `g.req.auth`.
- Without `groupsDataSource`, the token is checked but the person gets no group of its own : only the API user decides.

## Require it

- `authProviders: ['google_token_generator']` (the `name` of the provider) in the settings of the APIs, tables or databases, or in `common.authProviders` of the secret.
- The call carries the API user token in `x-am-authorization`, and the token of the provider in its header.
- `testObj` in the provider is the person the API testing page pretends to be.

## A provider of your own

For any other system, write a **Custom** provider : a token generator, which answers the token API for it, and a token validator, which says whether a token is valid, in any of the [languages](https://docs.apimaker.dev/v4/docs/languages/index.html). The app sends its token in `x-custom-authorization`, and your code reads the result in `g.req.auth.authCustom`. See [the example](https://docs.apimaker.dev/v4/examples/req/auth/authCustom.html).

## Related

- [Auth of a database user](https://docs.apimaker.dev/v4/docs/authorization/AMDB.html) · [API group permissions](https://docs.apimaker.dev/v4/docs/apis-security/api-group-permission.html) · [Who calls : g.req.auth](https://docs.apimaker.dev/v4/examples/req/auth/auth.html)
