# Sign in with STX

> OpenID Connect sign-in: the redirect, the callback and the verified identity.

Source: https://docs.stxapp.io/sdks/python/reference/connect/

> **Availability.** Available on US demo now. Live access is coming soon in the US and Ontario. See [Environments](https://docs.stxapp.io/environments/).

## `AsyncConnect`

Sign in with STX for one exchange.

```python
connect = AsyncConnect(
    issuer="https://demo.stxapp.io", client_id=CLIENT_ID,
    client_secret=CLIENT_SECRET, redirect_uri="https://your.app/auth/stx/callback",
    scopes=["balance.read", "orders.read"],
)
started = await connect.start(connection="google")   # redirect to started.url
...
done = await connect.finish(request_url, started.saved())
done.identity.sub, done.tokens.refresh_token
```

Raises `STXNotAvailableError` (`connect`) on an exchange that does
not publish OpenID Connect discovery.

### Methods

#### `configuration()`

```python
configuration() -> Dict[str, Any]
```

The discovery document, fetched once and cached.

#### `disconnect()`

```python
disconnect(tokens: TokenSet) -> None
```

End the member's connection: revokes the refresh token (or the
access token when there is none).

| Parameter | Type | Description |
|---|---|---|
| `tokens` | `TokenSet` |  |

#### `finish()`

```python
finish(callback: CallbackInput, saved: SavedSignIn) -> FinishedSignIn
```

Check the callback against `saved`, exchange the code and verify
the ID token. The state is checked before anything the callback says
is believed. Raises `STXOAuthException` (`invalid_state`,
`invalid_id_token`...) or the callback's typed error.

| Parameter | Type | Description |
|---|---|---|
| `callback` | `CallbackInput` |  |
| `saved` | `SavedSignIn` |  |

#### `oauth()`

```python
oauth() -> AsyncOAuthClient
```

The underlying `AsyncOAuthClient`, on the discovered endpoints.

#### `refresh()`

```python
refresh(refresh_token: str) -> TokenSet
```

STX rotates refresh tokens: store whatever comes back.

| Parameter | Type | Description |
|---|---|---|
| `refresh_token` | `str` |  |

#### `revoke()`

```python
revoke(token: str, token_type_hint: Optional[str] = None) -> None
```

Revoke one token. A refresh token ends the member's connection.

| Parameter | Type | Description |
|---|---|---|
| `token` | `str` |  |
| `token_type_hint` | `Optional[str]` |  |

#### `start()`

```python
start(*, connection: Optional[str] = None, login_hint: Optional[str] = None, scopes: ScopeInput = None, redirect_uri: Optional[str] = None, prompt: Optional[str] = None) -> StartedSignIn
```

A sign-in to send the member's browser to. `openid` is always
requested. `connection` (`google`, `apple`, `x`) goes straight
to that provider; `login_hint` preselects the member's email.

| Parameter | Type | Description |
|---|---|---|
| `connection` | `Optional[str]` |  |
| `login_hint` | `Optional[str]` |  |
| `scopes` | `ScopeInput` |  |
| `redirect_uri` | `Optional[str]` |  |
| `prompt` | `Optional[str]` |  |

#### `user_info()`

```python
user_info(access_token: str, *, expected_sub: Optional[str] = None) -> ConnectIdentity
```

The member's claims from the userinfo endpoint, read with their
access token (it must carry `openid`). Pass the `sub` you stored
and an answer about anyone else is refused.

| Parameter | Type | Description |
|---|---|---|
| `access_token` | `str` |  |
| `expected_sub` | `Optional[str]` |  |

#### `verify_id_token()`

```python
verify_id_token(token: str, *, nonce: Optional[str] = None) -> Dict[str, Any]
```

Verify an ID token and return its claims: the signature against the
issuer's published keys (RS256 or ES256), `iss`, `aud`/`azp`,
`exp`/`iat` within `clock_skew`, `nonce` and `sub`.

| Parameter | Type | Description |
|---|---|---|
| `token` | `str` |  |
| `nonce` | `Optional[str]` |  |

## `Connect`

Blocking Sign in with STX. Same arguments and methods as
`AsyncConnect`, without `await`.

### Methods

#### `configuration()`

```python
configuration() -> Dict[str, Any]
```

#### `disconnect()`

```python
disconnect(tokens: TokenSet) -> None
```

| Parameter | Type | Description |
|---|---|---|
| `tokens` | `TokenSet` |  |

#### `finish()`

```python
finish(callback: CallbackInput, saved: SavedSignIn) -> FinishedSignIn
```

| Parameter | Type | Description |
|---|---|---|
| `callback` | `CallbackInput` |  |
| `saved` | `SavedSignIn` |  |

#### `refresh()`

```python
refresh(refresh_token: str) -> TokenSet
```

| Parameter | Type | Description |
|---|---|---|
| `refresh_token` | `str` |  |

#### `revoke()`

```python
revoke(token: str, token_type_hint: Optional[str] = None) -> None
```

| Parameter | Type | Description |
|---|---|---|
| `token` | `str` |  |
| `token_type_hint` | `Optional[str]` |  |

#### `start()`

```python
start(**kwargs: Any) -> StartedSignIn
```

| Parameter | Type | Description |
|---|---|---|
| `kwargs` | `Any` |  |

#### `user_info()`

```python
user_info(access_token: str, *, expected_sub: Optional[str] = None) -> ConnectIdentity
```

| Parameter | Type | Description |
|---|---|---|
| `access_token` | `str` |  |
| `expected_sub` | `Optional[str]` |  |

#### `verify_id_token()`

```python
verify_id_token(token: str, *, nonce: Optional[str] = None) -> Dict[str, Any]
```

| Parameter | Type | Description |
|---|---|---|
| `token` | `str` |  |
| `nonce` | `Optional[str]` |  |

## `StartedSignIn`

`start()`'s result: send the browser to `url`, keep the rest
(`saved()`) in the session.

### Attributes

| Attribute | Type | Description |
|---|---|---|
| `state` | `str` |  |
| `code_verifier` | `str` |  |
| `nonce` | `str` |  |
| `redirect_uri` | `Optional[str]` |  |
| `url` | `str` |  |

### Methods

#### `from_dict()`

```python
from_dict(data: Dict[str, Any]) -> SavedSignIn
```

| Parameter | Type | Description |
|---|---|---|
| `data` | `Dict[str, Any]` |  |

#### `saved()`

```python
saved() -> SavedSignIn
```

#### `to_dict()`

```python
to_dict() -> Dict[str, Any]
```

## `SavedSignIn`

What to keep in your server session between `start` and `finish`.
`to_dict()` / `from_dict()` for session storage.

### Attributes

| Attribute | Type | Description |
|---|---|---|
| `state` | `str` |  |
| `code_verifier` | `str` |  |
| `nonce` | `str` |  |
| `redirect_uri` | `Optional[str]` |  |

### Methods

#### `from_dict()`

```python
from_dict(data: Dict[str, Any]) -> SavedSignIn
```

| Parameter | Type | Description |
|---|---|---|
| `data` | `Dict[str, Any]` |  |

#### `to_dict()`

```python
to_dict() -> Dict[str, Any]
```

## `FinishedSignIn`

### Attributes

| Attribute | Type | Description |
|---|---|---|
| `tokens` | `TokenSet` |  |
| `identity` | `ConnectIdentity` |  |

## `ConnectIdentity`

The member, from the verified ID token or the userinfo endpoint.

`sub` is the member's stable STX id for your app: key your user record
on it, not on the email.

### Attributes

| Attribute | Type | Description |
|---|---|---|
| `sub` | `str` |  |
| `email` | `Optional[str]` |  |
| `email_verified` | `Optional[bool]` |  |
| `claims` | `Dict[str, Any]` |  |
