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

# User Login

> Login and token refresh using OAuth2 token endpoint

OAuth2 token endpoint supporting password grant (login) and refresh token grant. This endpoint authenticates users and returns access tokens for API access.

## Password Grant (Login)

Authenticate a user with email/phone and password to receive access and refresh tokens.

<RequestExample>
  ```bash cURL
  curl -X POST "http://localhost:8080/token?grant_type=password" \
    -H "Content-Type: application/json" \
    -d '{
      "email": "user@example.com",
      "password": "securepassword123"
    }'
  ```

  ```javascript JavaScript
  const response = await fetch('http://localhost:8080/token?grant_type=password', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      email: 'user@example.com',
      password: 'securepassword123'
    }),
  });

  const authData = await response.json();
  ```

  ```python Python
  import requests

  data = {
      "email": "user@example.com",
      "password": "securepassword123"
  }

  response = requests.post(
      'http://localhost:8080/token?grant_type=password', 
      json=data
  )
  auth_data = response.json()
  ```

  ```go Go
  package main

  import (
      "bytes"
      "encoding/json"
      "net/http"
  )

  func main() {
      data := map[string]string{
          "email":    "user@example.com",
          "password": "securepassword123",
      }
      
      jsonData, _ := json.Marshal(data)
      
      resp, err := http.Post(
          "http://localhost:8080/token?grant_type=password",
          "application/json",
          bytes.NewBuffer(jsonData),
      )
      // Handle response...
  }
  ```
</RequestExample>

## Query Parameters

<ParamField query="grant_type" type="string" required>
  The OAuth2 grant type. Use `password` for login or `refresh_token` for token refresh.
</ParamField>

## Request Body (Password Grant)

<ParamField body="email" type="string">
  User's email address. Either email or phone is required.
</ParamField>

<ParamField body="phone" type="string">
  User's phone number in international format. Either email or phone is required.
</ParamField>

<ParamField body="password" type="string" required>
  User's password.
</ParamField>

## Refresh Token Grant

Use a refresh token to obtain new access tokens without re-authentication.

<RequestExample>
  ```bash cURL
  curl -X POST "http://localhost:8080/token?grant_type=refresh_token" \
    -H "Content-Type: application/json" \
    -d '{
      "refresh_token": "your_refresh_token_here"
    }'
  ```

  ```javascript JavaScript
  const response = await fetch('http://localhost:8080/token?grant_type=refresh_token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      refresh_token: 'your_refresh_token_here'
    }),
  });

  const authData = await response.json();
  ```
</RequestExample>

## Request Body (Refresh Token Grant)

<ParamField body="refresh_token" type="string" required>
  The refresh token obtained from a previous authentication.
</ParamField>

## Response

<ResponseField name="access_token" type="string">
  JWT access token for authenticating API requests
</ResponseField>

<ResponseField name="token_type" type="string">
  Token type, always "bearer"
</ResponseField>

<ResponseField name="expires_in" type="integer">
  Token expiration time in seconds (typically 3600 for 1 hour)
</ResponseField>

<ResponseField name="expires_at" type="integer">
  Token expiration timestamp (Unix timestamp)
</ResponseField>

<ResponseField name="refresh_token" type="string">
  Refresh token for obtaining new access tokens
</ResponseField>

<ResponseField name="user" type="object">
  User information object
</ResponseField>

<ResponseExample>
  ```json Response
  {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjQwOTk1MjAwLCJpYXQiOjE2NDA5MDg4MDAsImlzcyI6Imh0dHBzOi8veW91ci1wcm9qZWN0LnN1cGFiYXNlLmNvL2F1dGgvdjEiLCJzdWIiOiIxMjNlNDU2Ny1lODliLTEyZDMtYTQ1Ni00MjY2MTQxNzQwMDAiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5jb20iLCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9...",
    "token_type": "bearer",
    "expires_in": 3600,
    "expires_at": 1640995200,
    "refresh_token": "refresh_token_string_here",
    "user": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "aud": "authenticated",
      "role": "authenticated",
      "email": "user@example.com",
      "phone": null,
      "email_confirmed_at": "2023-01-01T00:00:00Z",
      "phone_confirmed_at": null,
      "last_sign_in_at": "2023-01-01T12:00:00Z",
      "app_metadata": {
        "provider": "email",
        "providers": ["email"]
      },
      "user_metadata": {
        "first_name": "John",
        "last_name": "Doe"
      },
      "created_at": "2023-01-01T00:00:00Z",
      "updated_at": "2023-01-01T12:00:00Z"
    }
  }
  ```
</ResponseExample>

## Error Responses

<ResponseExample>
  ```json 400 - Invalid Credentials
  {
    "code": 400,
    "msg": "Invalid credentials",
    "details": "Email or password is incorrect"
  }
  ```

  ```json 400 - Invalid Refresh Token
  {
    "code": 400,
    "msg": "Invalid refresh token",
    "details": "Refresh token is expired or invalid"
  }
  ```

  ```json 422 - Email Not Confirmed
  {
    "code": 422,
    "msg": "Email not confirmed",
    "details": "Please confirm your email before signing in"
  }
  ```

  ```json 429 - Rate Limited
  {
    "code": 429,
    "msg": "Too many requests",
    "details": "Rate limit exceeded. Try again later."
  }
  ```
</ResponseExample>

## Using Access Tokens

Include the access token in the Authorization header for authenticated requests:

```http
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```

Example authenticated request:

```bash
curl -X GET "http://localhost:8080/user" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json"
```

## Token Refresh Strategy

Implement automatic token refresh in your application:

```javascript
class AuthClient {
  constructor() {
    this.accessToken = null;
    this.refreshToken = null;
  }

  async refreshAccessToken() {
    const response = await fetch('/token?grant_type=refresh_token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ refresh_token: this.refreshToken })
    });

    const data = await response.json();
    this.accessToken = data.access_token;
    this.refreshToken = data.refresh_token;
  }

  async makeRequest(url, options = {}) {
    // Add auth header
    const headers = {
      'Authorization': `Bearer ${this.accessToken}`,
      ...options.headers
    };

    let response = await fetch(url, { ...options, headers });

    // If token expired, refresh and retry
    if (response.status === 401) {
      await this.refreshAccessToken();
      headers['Authorization'] = `Bearer ${this.accessToken}`;
      response = await fetch(url, { ...options, headers });
    }

    return response;
  }
}
```

## Phone Number Login

To login with a phone number instead of email:

```json
{
  "phone": "+1234567890",
  "password": "securepassword123"
}
```

## Rate Limiting

This endpoint is rate limited to prevent brute force attacks:

* **Password Grant**: 5 attempts per minute per IP address
* **Refresh Token Grant**: 10 requests per minute per user

## Security Features

* **Secure Password Hashing**: Passwords are verified using bcrypt
* **Token Rotation**: Refresh tokens are rotated on each use
* **Rate Limiting**: Protection against brute force attacks
* **Audit Logging**: All authentication attempts are logged

## Next Steps

After successful authentication:

1. **Store tokens securely** - Save access and refresh tokens
2. **Make authenticated requests** - Use the access token in API calls
3. **Handle token expiration** - Implement automatic refresh logic
4. **Implement logout** - Use the [logout endpoint](/api-reference/user/logout)
