# User login

For you are authenticate in OpenGate you have to do LOG-IN to obtain a token [JWT](../../../../security/authentication/jwt/) or an [ApiKey](../../../../security/authentication/apikey/):

## Do login

### Basic login

Do you need an email and password.

```mermaid
flowchart TD
    CU["CREATE User"] --> V{"Valid User"}
    V -- No --> E400["ERROR 400<br>Json malformed"]
    V -- "Yes, LOG-IN" --> LOGIN["Do LOG-IN<br>email and password"]
    LOGIN --> VC{"Valid<br>email and password"}
    VC -- No --> E401["ERROR 401<br>Bad credentials"]
    VC -- Yes --> OK["Return: 200 OK<br>Return data (JWT and ApiKey)"]

    classDef error fill:#f9d0d0,stroke:#c85a5a,color:#000
    classDef ok fill:#a8ecd0,stroke:#2b9c6e,color:#000
    class E400,E401 error
    class OK ok
```

### Login with Two Factor Authentication

Do you need an email, password and an 2FA Code generated.

#### How can you generate the 2FA code?

First, you have to configure your application to generate codes.

Configure your application

When you do login in OpenGate, the first time **after configuring 2FA**, the LOG-IN service responds with an error code 401, but in the headers contains an URL in the attribute *location* with the parameters of configuration.

You have to use this parameters to configure your application to generate the codes.

The URL of location will be like this `otpauth://totp/2FA?secret=CAX3VP5O7GWZXUDWQOK4267DGXXSFIDQ&issuer=OpenGate&algorithm=SHA1&digits=6&period=30`

Description of the attributes of the URL:

- **secret**: contain the secret key to generate codes.
- **period**: define the time of validation of the code.
- **digits**: define the length of the code generated.
- **algorithm**: define the Algorithm used to generate the codes.
- **issuer**: define the subject, the name of the server.

Some applications only need the secret field, and others need all parameters.

You can see the flow of this process in follow diagram:

```mermaid
flowchart TD
    CU["CREATE or UPDATE USER<br>with 2FA"] --> V{"Valid User<br>with 2FA type"}
    V -- No --> E400["ERROR 400<br>Json malformed"]
    V -- "Yes, LOG-IN" --> LOGIN["Do LOG-IN<br>without 2FA Code"]
    LOGIN --> FIRST{"First time"}
    FIRST -- No --> E401A["ERROR 401<br>Bad Credentials<br>or Bad 2Fa Code sent"]
    FIRST -- Yes --> HDR["Return: ERROR 401<br>Headers with URL 2FA"]
    HDR --> APP["With URL - Configure APP"]
    APP --> GEN["Generate 2FA code<br>with the application"]
    GEN --> LOGIN2["Do LOG-IN with 2FA"]
    LOGIN2 --> VC{"Valid<br>email and password"}
    VC -- No --> E401B["ERROR 401<br>Bad Credentials"]
    VC -- Yes --> EXP{"Code expired<br>Code invalid"}
    EXP -- No --> OK["Return 200 OK<br>Return data (JWT and ApiKey)"]
    EXP -- Yes --> E401C["401 ERROR<br>Invalid Code"]

    classDef error fill:#f9d0d0,stroke:#c85a5a,color:#000
    classDef ok fill:#a8ecd0,stroke:#2b9c6e,color:#000
    classDef step fill:#addcf8,stroke:#2b7cb8,color:#000
    class E400,E401A,E401B,E401C,HDR error
    class OK ok
    class LOGIN,APP,GEN,LOGIN2 step
```

### 2FA error responses

Every 2FA failure returns `401 Unauthorized`, so the **error code** is what tells the cases apart:

| Code | Situation | Context |
|---|---|---|
| `0x000065` | First login after configuring 2FA. Read the `location` header to configure your application. | `2FA` |
| `0x000065` | 2FA is configured but no code was sent. | `2FaCode` is null |
| `0x000066` | The code sent is invalid or expired. | `2FaCode` |
| `0x000067` | A code was sent but the user has no 2FA configured. Log in without the TOTP code. | `2FaCode` |

An expired **password** is a different case: it returns `403` with code `0x010063`.
