# Log in a citizen

This how-to guides you through the steps required to ensure that only citizens authenticated with [ID-porten](/auth/idporten.md) can access your application.

## Prerequisites

Before you begin, ensure that you have:

- Familiarized yourselves with [the login proxy concepts](/auth/explanations.md#login-proxy).
- [Exposed your application with an ingress](/workloads/application/how-to/expose.md).

## Configure your application

Enable the login proxy for ID-porten in your application configuration:

```yaml
spec:
  idporten:
    sidecar:
      enabled: true
```

> **Login proxy is only available in GCP**
> Login proxy is only available in GCP clusters, and will not work in on-prem clusters.

See the [Nais application reference](/workloads/application/reference/spec.md#idportensidecar) for the complete specifications with all possible options.

Now that your application is configured, you will need to handle inbound requests in your application code.

## Handle inbound requests

As long as the user is authenticated, all requests to your application at the server-side will include the `Authorization` header with the user's `access_token` as a [Bearer token](/auth/explanations.md#bearer-token).

Your application is responsible for verifying that this token is present and valid. To do so, follow these steps:

### Handle missing or empty `Authorization` header

If the `Authorization` header is missing or empty, the citizen is unauthenticated.

Return an appropriate HTTP status code to the frontend, and redirect the citizen's user agent to the [login endpoint](/auth/reference.md#login-endpoint):

```
https://<ingress>/oauth2/login
```

### Validate token in `Authorization` header

If the `Authorization` header is present, validate the [JWT Bearer token](/auth/explanations.md#bearer-token) within.
If invalid, redirect the citizen to the [login endpoint](/auth/reference.md#login-endpoint):

```
https://<ingress>/oauth2/login
```

> **Library for token validation**
> For JavaScript-based applications, we recommend using [navikt/oasis](https://github.com/navikt/oasis).
> This provides native utilities for validating tokens as well as [exchanging these for new tokens when consuming other APIs](#next-steps).

> Otherwise, you can implement validation with the steps below.

The steps below describe how to validate a token using the *token introspection endpoint*.

> **What is the token introspection endpoint?**
> The token introspection endpoint simplifies the token validation process, but does require a network call.

> If your application uses a library or framework that supports validering JWTs, you can alternatively let these handle the validation instead.
> See [the reference page for manually validating tokens](/auth/idporten/reference.md#manual-token-validation).

Send a HTTP POST request to the endpoint found in the `NAIS_TOKEN_INTROSPECTION_ENDPOINT` environment variable.
The request must have a `Content-Type` header set to either:

- `application/json` or
- `application/x-www-form-urlencoded`

The body of the request should contain the following parameters:

| Parameter | Example Value | Description |
| :--- | :--- | :--- |
| `identity_provider` | `idporten` | Always `idporten`. |
| `token` | `eyJra...` | The access token you wish to validate. |

**application/json**

```http
POST ${NAIS_TOKEN_INTROSPECTION_ENDPOINT} HTTP/1.1
Content-Type: application/json

{
    "identity_provider": "idporten",
    "token": "eyJra..."
}
```

**application/x-www-form-urlencoded**

```http
POST ${NAIS_TOKEN_INTROSPECTION_ENDPOINT} HTTP/1.1
Content-Type: application/x-www-form-urlencoded

identity_provider=idporten&
token=eyJra...
```

The response is always a HTTP 200 OK response with a JSON body.

It always contains the `active` field, which is a boolean value that indicates whether the token is valid or not.

##### Success response

If the token is valid, the response will additionally contain **all** the token's claims:

```json
{
    "active": true,
    "exp": 1730980893,
    "iat": 1730977293,
    ...
}
```

Claims are copied verbatim from the token to the response.

> **Which claims are validated by the endpoint?**
> The endpoint only validates the token's signature and its [standard claims](/auth/explanations.md#claims-validation).

> [Other claims](/auth/idporten/reference.md#claims) are included in the response, but are not validated.
> Your application must validate these other claims according to your own requirements.

##### Error response

If the token is invalid, the only additional field in the response is the `error` field:

```json
{
    "active": false,
    "error": "token is expired"
}
```

The `error` field contains a human-readable error message that describes why the token is invalid.

## Next steps

The citizen is now authenticated and can access your application.
You can extract [the claims](/auth/idporten/reference.md#claims) from the subject token found in the `Authorization` header to assert the user's identity.

However, the token is **only valid for *your* application**.
To consume other APIs on behalf of the citizen, [exchange the token for a new token that targets a specific API](/auth/tokenx/how-to/consume.md).

## Related pages

🎯 Learn how to [consume other APIs on behalf of a citizen](/auth/tokenx/how-to/consume.md)

📚 [ID-porten reference](/auth/idporten/reference.md)

📚 [Login proxy reference](/auth/reference.md#login-proxy)
