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

# Using Client Tokens

> This document explains how to handle client tokens via both HTTP and gRPC.

## HTTP

Client tokens can be presented via HTTP requests in two different valid ways. This choice allows us to support two different types of workloads.

### 1. `Authorization` Header

For applications that communicate with Flipt over HTTP, the `Authorization` header is most appropriate.
It must be provided in the form `Authorization: Bearer <client_token>`.

The following examples illustrate this in the context of various programming languages:

<CodeGroup>
  ```go client.go theme={null}
  import (
    "context"
    "net/http"
  )

  func main() {
    req := http.NewRequest("GET", "https://flipt.your.instance/api/v1/flags", nil)
    req.Header.Set("Authorization", "Bearer gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=")

    resp, err := http.Do(req)
    // ...
  }
  ```

  ```typescript client.ts theme={null}
  import fetch from 'node-fetch';

  const headers = { 'Authorization': 'Bearer gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=' }
  const response = await fetch('https://flipt.your.instance/api/v1/flags', { headers: headers })
  ```

  ```python client.py theme={null}
  import requests

  def doRequest():

    headers ={"Authorization": "Bearer gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc="}
    requests.get("https://flipt.your.instance/api/v1/flags", headers=headers)

    return
  ```
</CodeGroup>

### 2. `Cookie` Header

<Warning>
  It's important to enable [CSRF](/v1/configuration/authentication#session)
  prevention in your Flipt configuration when using a "session compatible"
  authentication method and `Cookie` based authentication in the browser.
</Warning>

For browser-based applications (e.g. Flipt's own user interface) we support supplying a client token via a particular `Cookie` called `flipt_client_token`.

<CodeGroup>
  ```go client.go theme={null}
  import (
    "context"
    "net/http"
  )

  func main() {
    req := http.NewRequest("GET", "https://flipt.your.instance/api/v1/flags", nil)
    req.AddCookie(&http.Cookie{
      Name: "flipt_client_token",
      Value: "gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=",
      }
    )

    resp, err := http.Do(req)
    // ...
  }

  ```

  ```typescript client.ts theme={null}
  import fetch from "node-fetch";

  const headers = {
    Cookie: "flipt_client_token=gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=",
  };

  const response = await fetch("https://flipt.your.instance/api/v1/flags", {
    headers: headers,
  });
  ```

  ```python client.py theme={null}
  import requests

  def doRequest():

    headers ={"Cookie": "flipt_client_token=gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc="}
    requests.get("https://flipt.your.instance/api/v1/flags", headers=headers)

    return
  ```
</CodeGroup>

This allows for stateful browser sessions to be established.

When using a "session compatible" authentication method (e.g. [OIDC](/v1/authentication/methods#oidc)), Flipt will automatically establish this cookie via a `Set-Cookie` response header during the authentication method exchange.

In a browser context this means subsequent API calls will be automatically authenticated given the API requests are invoked with credentials included (cookies are enabled). Flipt's UI leverages this mechanism for its login functionality.

## GRPC

For gRPC we use the [Metadata](https://grpc.io/docs/what-is-grpc/core-concepts/#metadata) functionality similar to HTTP Headers.
The lower-case `authorization` metadata key should be supplied with a single string `Bearer <client-token>` to any RPC calls.

### Example

The following example authenticates a single gRPC client request:

```go rpc.go theme={null}
func DoRequest(ctx context.Context, flagKey string) {
  ctx := metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=")

  flag, err := flipt.GetFlags(ctx, &flipt.GetFlagRequest{
    Key: flagKey,
  })

  //...
}
```

This subsequent example demonstrates using a client unary interceptor, which authenticates all outgoing requests:

```go interceptor.go theme={null}
func AuthUnaryClientInterceptor(optFuncs ...CallOption) grpc.UnaryClientInterceptor {
    return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
        ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=")
        return invoker(ctx, method, req, reply, cc, opts...)
	}
}
```
