slackline/oauth

Install an app with OAuth v2, or sign users in with Sign in with Slack.

  1. Send the user to authorize_url(...).
  2. Slack redirects back to your redirect_uri with code and state.
  3. Check the state with verify_state, then exchange the code with slackline/api/oauth.v2_access using an anonymous client.
let url =
  oauth.authorize_url(
    oauth.Authorize(
      ..oauth.authorize(client_id: "123.456"),
      scopes: ["chat:write", "commands"],
      state: Some(oauth.sign_state(secret)),
    ),
  )

See https://docs.slack.dev/authentication/installing-with-oauth, https://docs.slack.dev/authentication/using-pkce and https://docs.slack.dev/authentication/sign-in-with-slack.

Types

The parameters of an OAuth v2 install link.

pub type Authorize {
  Authorize(
    endpoint: String,
    client_id: String,
    scopes: List(String),
    user_scopes: List(String),
    redirect_uri: option.Option(String),
    state: option.Option(String),
    team: option.Option(String),
    code_challenge: option.Option(String),
  )
}

Constructors

  • Authorize(
      endpoint: String,
      client_id: String,
      scopes: List(String),
      user_scopes: List(String),
      redirect_uri: option.Option(String),
      state: option.Option(String),
      team: option.Option(String),
      code_challenge: option.Option(String),
    )

    Arguments

    endpoint

    Defaults to authorize_endpoint.

    client_id

    Your app’s client id.

    scopes

    Scopes for the bot token.

    user_scopes

    Scopes for a user token, if your app acts on behalf of users.

    redirect_uri

    Must match, or be below, a redirect url in your app settings.

    state

    An opaque value echoed back to your redirect url. Use sign_state.

    team

    A workspace (T…) or organization (E…) id to suggest. Slack treats it as a hint. Trust the oauth.v2.access response.

    code_challenge

    A PKCE challenge from pkce_challenge. Sends code_challenge_method=S256 alongside it.

The parameters of a Sign in with Slack link.

pub type OpenIdAuthorize {
  OpenIdAuthorize(
    endpoint: String,
    client_id: String,
    scopes: List(String),
    redirect_uri: String,
    state: option.Option(String),
    nonce: option.Option(String),
    team: option.Option(String),
  )
}

Constructors

  • OpenIdAuthorize(
      endpoint: String,
      client_id: String,
      scopes: List(String),
      redirect_uri: String,
      state: option.Option(String),
      nonce: option.Option(String),
      team: option.Option(String),
    )

    Arguments

    scopes

    Usually ["openid", "profile", "email"].

    nonce

    Echoed in the id token, so you can detect replays.

Why a state value was rejected.

pub type StateError {
  InvalidState
  ExpiredState
}

Constructors

  • InvalidState

    The signature does not match, so the state was forged or mangled.

  • ExpiredState

    The state is older than state_max_age_seconds.

Values

pub fn authorize(client_id client_id: String) -> Authorize

An install link for client_id with nothing else set.

pub const authorize_endpoint: String

Where to send users to install an app on the commercial Slack cloud.

pub fn authorize_url(authorize: Authorize) -> String

Renders the install link.

pub const gov_authorize_endpoint: String

Where to send users to install an app on GovSlack.

pub fn openid_authorize(
  client_id client_id: String,
  redirect_uri redirect_uri: String,
) -> OpenIdAuthorize

A Sign in with Slack link asking for openid, profile and email.

pub const openid_authorize_endpoint: String

Where to send users for Sign in with Slack (OpenID Connect).

pub fn openid_authorize_url(authorize: OpenIdAuthorize) -> String

Renders the Sign in with Slack link.

pub fn pkce_challenge(verifier: String) -> String

The S256 code challenge for a verifier.

pub fn pkce_verifier() -> String

A fresh random PKCE code verifier. Keep it and send it as code_verifier in the code exchange.

pub fn sign_state(secret: String) -> String

A tamper-proof state value signed with secret and stamped with the current time. Use any long random string you keep private as the secret.

pub fn sign_state_at(secret: String, now: Int) -> String

sign_state at an explicit unix time.

pub const state_max_age_seconds: Int

How long a signed state stays valid, in seconds.

pub fn verify_state(
  secret: String,
  state: String,
) -> Result(Nil, StateError)

Checks a state value produced by sign_state.

pub fn verify_state_at(
  secret: String,
  state: String,
  now: Int,
) -> Result(Nil, StateError)

verify_state at an explicit unix time.

✨ Search Document