> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dintero.com/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.dintero.com/feedback

```json
{
  "path": "/docs/auth-service",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Authentication Service

> Add login, account creation, and single sign-on for end users to your apps using the Dintero authentication service, scopes, and access tokens.

## Introduction to Authentication Service

Our simple authentication service let your customers/end-users create account
and use the same account to login to your multiple applications as MyPage,
Loyalty apps, Online store etc.

## Add login to Your Single-Page App

### How it works

In a single-page application (SPA):

1. The user enters email/password in a login form hosted on the SPA and POST
   the details to the [login] resource.
2. API responds with the user's access token.

### Configure a login client

A client with scope `accounts:auth:users` is required to access the [login] resource.
Additional scopes must be added to grant access to user specific resources.

| scope                                | description                                 |
| ------------------------------------ | ------------------------------------------- |
| `accounts:auth:users`                | grant access to login and creating new user |
| `customer_customers:read`            | grant `read-only` to user                   |
| `customer_customers:write`           | grant `write-only` to user                  |
| `customer_discounts:read`            | grant `read-only` to user discounts         |
| `customer_receipts:read`             | grant `read-only` to user receipts          |
| `create:accounts:auth:refresh_token` | enable issuing `refresh_token`              |

> **Note**: A login client with required grants can be created in [backoffice].

### Login user with email/password

In the SPA, use the "login client" to get an [access token]. The access token is
required as authentication when accessing the [login] resource.

```curl theme={null}
curl -X POST https://{server}/v1/accounts/{aid}/auth/token \
  -H 'Content-Type: application/json' \
  -u client_id:client_secret \
  -d '{"grant_type":"client_credentials", "audience":"{audience}" }'
```

where `audience` is the audience that was used when creating the login client.

Use the access token when requesting [login] of a user:

```curl theme={null}
curl -X POST https://{server}/v1/accounts/{aid}/customers/login \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer {client_access_token} \
  -d '{"email":"", "password": "", "type": "", "audience":"{audience}"}'
```

A user access token will be returned on success.

> **Note**: The user `password` must be set when [creating the user].

### Reset password

Reset of user password is done in three steps

1. Request [change password], the user will receive a verification code
   via email.
2. Login the user by verification code:

```curl theme={null}
curl -X POST https://{server}/v1/accounts/{aid}/auth/token
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer {client_access_token} \
  -d '{"grant_type":"authorization_code", "audience":"{audience}", "verification_code: "" }'
```

3. Update the user with [change password].

## Refresh Token

A Refresh Token allows the application to ask Account-Auth service to
issue a new Access Token without having to re-authenticate the user.

This will work as long as the Refresh Token has not been revoked.

> **Note** A Single-Page Application should not ever receive a Refresh Token,
> this information is sensitive and should not be exposed client-side in a browser.

### Get a Refresh Token

To get a Refresh Token, you must use a client with a grant that includes the

* `create:account:auth:refresh_token`

scope when requesting for a token.

```curl theme={null}
curl -X POST https://{server}/v1/accounts/{aid}/customers/login \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer {client_with_refresh_scope_access_token} \
  -d '{"email":"", "password": "", "type": "", "audience":"{audience}"}'
```

The response should contain an Access Token and a Refresh Token

```json theme={null}
{
    "access_token": "eyJhbGci...t7P4",
    "refresh_token": "eyGmkde...t3M3",
    "token_type": "Bearer",
    "expires_in": 86400
}
```

> **Note**: Refresh Token must be stored securely by an application since they
> allow a user to remain authenticated essentially forever

### Use a Refresh Token

To exchange the Refresh Token you received during authorization for a new
Access Token, make a `POST` request to the `/accounts/{oid}/auth/token` endpoint
using `grant_type=refresh_token`.

```curl theme={null}
curl -X POST https://{server}/v1/accounts/{aid}/auth/token \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer {client_with_refresh_scope_access_token} \
  -d '{"grant_type":"refresh_token","refresh_token":"eyGmkde...t3M3"}'
```

The response include a new Access Token, its type, its lifetime (in seconds)

```json theme={null}
{
    "access_token": "eyJhbGci...t7P4",
    "token_type": "Bearer",
    "expires_in": 86400
}
```

> You should only ask for a new token if the Access Token has expired. For
> example, it's a bad practice to call the endpoint to get a new Access Token
> every time you call an API.

### Revoke a Refresh Token

Since Refresh Token never expire, it is essential to be able to revoke them
in case they get compromised.

You can [revoke a refresh token] by making a `POST` request to the
`/accounts/{oid}/auth/token` endpoint using `token=REFRESH_TOKEN_TO_REVOKE`

```curl theme={null}
curl -X POST https://{server}/v1/accounts/{aid}/auth/token \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer {client_with_refresh_scope_access_token} \
  -d '{"token":"eyGmkde...t3M3"}'
```

## Add Vipps Login

### How it works

In a single-page application (SPA):

1. The SPA creates a login link to login with Vipps
2. The user opens the login link and completes the login in the Vipps App
3. The SPA handles the redirect from Vipps and request access token via the API

### Configure grant for the login client

Login with Vipps requires a client grant with `oidc` configured

```json theme={null}
{
  "client_id": "{client_id}",
  "audience": "{audience}",
  "type": "authorization_code",
  "scope": [
    "user:customers",
    "user:customers:/users?type=customer&phone_number"
  ],
  "oidc": {
    "authority": "https://api.vipps.no/access-management-1.0/access/.well-known/openid-configuration",
    "client_id": "{vipps-client-id}",
    "client_secret": "{vipps-client-secret}"
  }
}
```

<Info>
  You can continue to support existing login with email or phone number by
  including the grant scopes:

  * **`user:customers:/users?type=customer&phone_number`**
  * **`user:customers:/users?type=customer&email`**

  The Vipps user will then be matched with existing user by matching the email or
  phone number provided by Vipps

  User consent is required when matching email or phone number [Vipps documentation]
</Info>

### Create Vipps Login URL

Use the [authorize with OIDC][authorize with OIDC] endpoint to create a Vipps
Login URL

```
GET: /auth/oidc/authorize?client_id={client_id} \
  &response_type=code&scope={scopes}&state={state} \
  &redirect_uri={redirect_uri}
```

**Query parameter examples**

| query parameters | example                    |
| ---------------- | -------------------------- |
| audience         | `{dintero-grant-audience}` |
| response\_type   | code                       |
| client\_id       | `{dintero-client-id}`      |
| state            | `{spa-generated-state}`    |
| redirect\_uri    | `{vipps-redirect-uri}`     |
| scope            | `{vipps-scopes}`           |

> See [Vipps documentation] for supported query
> parameters

### Get user token from Vipps login

After a successful authentication, the user agent is redirected to the
`{vipps-redirect-uri}` with the following parameters added to the query

| query parameters | example                                                       |
| ---------------- | ------------------------------------------------------------- |
| code             | Authorization code generated by Vipps                         |
| state            | The exact value received from the client during authorization |

Use the [token verified by OIDC] endpoint to get the user token

```json theme={null}
{
  "grant_type": "authorization_code",
  "code": "{code}",
  "client_id": "{dintero-client-id}",
  "redirect_uri": "{vipps-redirect-uri}",
  "audience": "{dintero-grant-audience}"
}
```

The response will look like this:

```json theme={null}
{
  "access_token": "eyJhbGci...t7P4",
  "token_type": "Bearer",
  "expires_in": 86400,
  "user_info": {
    "authority": "https://identityserver.example.com/access",
    "value": {
      "sub": "c06c4afe-d9e1-4c5d-939a-177d752a0944",
      "name": "Ada Lovelace"
    }
  }
}
```

[authorize with OIDC]: /management-auth-api.html#operation/aid_auths_oidc_authorize_get

[token verified by OIDC]: /management-auth-api.html#operation/aid_auths_oidc_token_post

[Vipps documentation]: https://github.com/vippsas/vipps-login-api/blob/master/vipps-login-api.md#oauth-20-authorize

[creating the user]: /api.html#operation/aid_customers_post

[access token]: /api.html#operation/aid_auths_oauth_token_post

[revoke a refresh token]: /api.html#operation/aid_auths_oauth_revoke_post

[change password]: /api.html#operation/aid_customers_change_password

[login]: /api.html#operation/aid_customers_login_post

[sign up]: https://onboarding.dintero.com/

[backoffice]: https://backoffice.dintero.com/
